From c9bcfa584aa98d20f372b2c7ec55b8b325a8c674 Mon Sep 17 00:00:00 2001 From: gamma0987 Date: Sat, 8 Aug 2026 00:01:14 +0200 Subject: [PATCH 01/11] fix: add missing gungraun dhat metrics --- .../src/adapters/rust/gungraun.rs | 5 +++++ .../src/results/adapter_results.rs | 20 +++++++++++++++++++ .../src/project/measure/built_in.rs | 12 +++++++++++ 3 files changed, 37 insertions(+) diff --git a/lib/bencher_adapter/src/adapters/rust/gungraun.rs b/lib/bencher_adapter/src/adapters/rust/gungraun.rs index cc169e63a..adc83e84a 100644 --- a/lib/bencher_adapter/src/adapters/rust/gungraun.rs +++ b/lib/bencher_adapter/src/adapters/rust/gungraun.rs @@ -214,12 +214,17 @@ fn dhat_tool_measures<'a>() .map(|(metric_name, json)| match metric_name.as_str() { gungraun::TotalBytes::NAME_STR => GungraunMeasure::TotalBytes(json), gungraun::TotalBlocks::NAME_STR => GungraunMeasure::TotalBlocks(json), + gungraun::TotalUnits::NAME_STR => GungraunMeasure::TotalUnits(json), + gungraun::TotalEvents::NAME_STR => GungraunMeasure::TotalEvents(json), + gungraun::TotalLifetimes::NAME_STR => GungraunMeasure::TotalLifetimes(json), gungraun::AtTGmaxBytes::NAME_STR => GungraunMeasure::AtTGmaxBytes(json), gungraun::AtTGmaxBlocks::NAME_STR => GungraunMeasure::AtTGmaxBlocks(json), gungraun::AtTEndBytes::NAME_STR => GungraunMeasure::AtTEndBytes(json), gungraun::AtTEndBlocks::NAME_STR => GungraunMeasure::AtTEndBlocks(json), gungraun::ReadsBytes::NAME_STR => GungraunMeasure::ReadsBytes(json), gungraun::WritesBytes::NAME_STR => GungraunMeasure::WritesBytes(json), + gungraun::MaximumBytes::NAME_STR => GungraunMeasure::MaximumBytes(json), + gungraun::MaximumBlocks::NAME_STR => GungraunMeasure::MaximumBlocks(json), _ => GungraunMeasure::Unknown, }) .collect() diff --git a/lib/bencher_adapter/src/results/adapter_results.rs b/lib/bencher_adapter/src/results/adapter_results.rs index 8bcdc81f0..d1b9d8602 100644 --- a/lib/bencher_adapter/src/results/adapter_results.rs +++ b/lib/bencher_adapter/src/results/adapter_results.rs @@ -100,12 +100,17 @@ pub enum GungraunMeasure { */ TotalBytes(JsonNewMetric), TotalBlocks(JsonNewMetric), + TotalUnits(JsonNewMetric), + TotalEvents(JsonNewMetric), + TotalLifetimes(JsonNewMetric), AtTGmaxBytes(JsonNewMetric), AtTGmaxBlocks(JsonNewMetric), AtTEndBytes(JsonNewMetric), AtTEndBlocks(JsonNewMetric), ReadsBytes(JsonNewMetric), WritesBytes(JsonNewMetric), + MaximumBytes(JsonNewMetric), + MaximumBlocks(JsonNewMetric), /* * Memcheck tool: @@ -430,6 +435,15 @@ impl AdapterResults { GungraunMeasure::TotalBlocks(json_metric) => { (built_in::gungraun::TotalBlocks::name_id(), json_metric) }, + GungraunMeasure::TotalUnits(json_metric) => { + (built_in::gungraun::TotalUnits::name_id(), json_metric) + }, + GungraunMeasure::TotalEvents(json_metric) => { + (built_in::gungraun::TotalEvents::name_id(), json_metric) + }, + GungraunMeasure::TotalLifetimes(json_metric) => { + (built_in::gungraun::TotalLifetimes::name_id(), json_metric) + }, GungraunMeasure::AtTGmaxBytes(json_metric) => { (built_in::gungraun::AtTGmaxBytes::name_id(), json_metric) }, @@ -448,6 +462,12 @@ impl AdapterResults { GungraunMeasure::WritesBytes(json_metric) => { (built_in::gungraun::WritesBytes::name_id(), json_metric) }, + GungraunMeasure::MaximumBytes(json_metric) => { + (built_in::gungraun::MaximumBytes::name_id(), json_metric) + }, + GungraunMeasure::MaximumBlocks(json_metric) => { + (built_in::gungraun::MaximumBlocks::name_id(), json_metric) + }, // Memcheck GungraunMeasure::MemcheckErrors(json_metric) => { (built_in::gungraun::MemcheckErrors::name_id(), json_metric) diff --git a/lib/bencher_json/src/project/measure/built_in.rs b/lib/bencher_json/src/project/measure/built_in.rs index 68f949fc9..d474c9a9d 100644 --- a/lib/bencher_json/src/project/measure/built_in.rs +++ b/lib/bencher_json/src/project/measure/built_in.rs @@ -185,6 +185,16 @@ pub mod gungraun { create_measure!(TotalBytes, "Total bytes", "total-bytes", BYTES); create_measure!(TotalBlocks, "Total blocks", "total-blocks", "blocks"); create_measure!(AtTGmaxBytes, "At t-gmax bytes", "at-t-gmax-bytes", BYTES); + + create_measure!(TotalUnits, "Total units", "total-units", "units"); + create_measure!(TotalEvents, "Total events", "total-events", "events"); + create_measure!( + TotalLifetimes, + "Total lifetimes", + "total-lifetimes", + "lifetimes" + ); + create_measure!( AtTGmaxBlocks, "At t-gmax blocks", @@ -195,6 +205,8 @@ pub mod gungraun { create_measure!(AtTEndBlocks, "At t-end blocks", "at-t-end-blocks", "blocks"); create_measure!(ReadsBytes, "Reads bytes", "reads-bytes", BYTES); create_measure!(WritesBytes, "Writes bytes", "writes-bytes", BYTES); + create_measure!(MaximumBytes, "Maximum bytes", "maximum-bytes", BYTES); + create_measure!(MaximumBlocks, "Maximum blocks", "maximum-blocks", "blocks"); // Memcheck create_measure!( From f1b3a7c26f328fd9e4ffbf30de56689480c8a3f7 Mon Sep 17 00:00:00 2001 From: gamma0987 Date: Sat, 8 Aug 2026 15:52:28 +0200 Subject: [PATCH 02/11] Implement gungraun json parser --- Cargo.lock | 36 +++ Cargo.toml | 1 + lib/bencher_adapter/Cargo.toml | 1 + .../src/adapters/rust/gungraun_json.rs | 264 ++++++++++++++++++ lib/bencher_adapter/src/adapters/rust/mod.rs | 7 +- 5 files changed, 308 insertions(+), 1 deletion(-) create mode 100644 lib/bencher_adapter/src/adapters/rust/gungraun_json.rs diff --git a/Cargo.lock b/Cargo.lock index 27ac9cb57..f44d0b922 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1084,6 +1084,7 @@ version = "0.6.11" dependencies = [ "bencher_json", "criterion", + "gungraun-summary", "literally", "nom", "ordered-float", @@ -3082,6 +3083,16 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +[[package]] +name = "either-or-both" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717164c227120ba9ddf3e2b32305fc0122741d3ee41a54968eae7573ee01933" +dependencies = [ + "indexmap", + "serde", +] + [[package]] name = "elliptic-curve" version = "0.13.8" @@ -4268,6 +4279,31 @@ dependencies = [ "subtle", ] +[[package]] +name = "gungraun-runner" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47c68c92812da579a2510a2cc702d5aa3251992b9662d4a98502ca46e0cbe16e" +dependencies = [ + "either-or-both", + "indexmap", + "serde", +] + +[[package]] +name = "gungraun-summary" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89f967da1beab0153f3f1e52408a71d3bd0fbea3c9e0bf0431f9a3a3c9e96130" +dependencies = [ + "either-or-both", + "gungraun-runner", + "indexmap", + "serde", + "serde_json", + "thiserror 2.0.18", +] + [[package]] name = "h2" version = "0.4.14" diff --git a/Cargo.toml b/Cargo.toml index d83c054cb..103486749 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -113,6 +113,7 @@ futures-util = "0.3" gix = { version = "0.83", default-features = false } gix-hash = { version = "0.25", features = ["sha1"] } git-validate = "0.7" +gungraun-summary = { version = "6" } hex = "0.4" http = "1.4" http-body-util = "0.1" diff --git a/lib/bencher_adapter/Cargo.toml b/lib/bencher_adapter/Cargo.toml index 63de9b1ed..ef4c11d93 100644 --- a/lib/bencher_adapter/Cargo.toml +++ b/lib/bencher_adapter/Cargo.toml @@ -12,6 +12,7 @@ plus = ["bencher_json/plus"] [dependencies] bencher_json = { workspace = true, features = ["server"] } +gungraun-summary.workspace = true literally.workspace = true nom.workspace = true ordered-float.workspace = true diff --git a/lib/bencher_adapter/src/adapters/rust/gungraun_json.rs b/lib/bencher_adapter/src/adapters/rust/gungraun_json.rs new file mode 100644 index 000000000..efe1292fe --- /dev/null +++ b/lib/bencher_adapter/src/adapters/rust/gungraun_json.rs @@ -0,0 +1,264 @@ +use bencher_json::{BenchmarkName, JsonNewMetric, project::report::JsonAverage}; + +use gungraun_summary::{ + either_or_both::EitherOrBoth, + util::SummaryByVersion, + v6::{ + CachegrindMetric, DhatMetric, ErrorMetric, EventKind, Metric, MetricsDiff, MetricsSummary, + ToolMetricSummary, ValgrindTool, + }, +}; + +use crate::{Adaptable, AdapterResults, Settings, results::adapter_results::GungraunMeasure}; + +pub struct AdapterRustGungraunJson; + +impl Adaptable for AdapterRustGungraunJson { + fn parse(input: &str, settings: Settings) -> Option { + match settings.average { + None => {}, + Some(JsonAverage::Mean | JsonAverage::Median) => { + return None; // 'gungraun' results are for a single run only. + }, + } + + // Clean up the input by removing ANSI escape codes: + let input = strip_ansi_escapes::strip_str(input); + + parse_multiple(&input).and_then(AdapterResults::new_gungraun) + } +} + +fn parse_multiple(input: &str) -> Option)>> { + let parsed = input.lines().filter_map(parse_line).collect::>(); + + (!parsed.is_empty()).then_some(parsed) +} + +fn parse_line(input: &str) -> Option<(BenchmarkName, Vec)> { + // Using the version aware gungraun_summary parsing method to simplify adapting gungraun summary + // version updates. At the moment there's just v6 + let summary = match gungraun_summary::util::parse_slice(input.as_bytes()) { + Ok(summary_by_version) => match summary_by_version { + SummaryByVersion::V6(benchmark_summary) => benchmark_summary, + _ => return None, + }, + Err(_) => return None, + }; + + let name: BenchmarkName = if let Some(id) = &summary.id { + format!("{}::{id}", summary.module_path) + } else { + summary.module_path + } + .parse() + .ok()?; + + let measures = summary + .profiles + .0 + .into_iter() + .flat_map(|profile| match profile.summaries.total.summary { + ToolMetricSummary::Cachegrind(metrics_summary) => { + parse_cachegrind_metrics_summary(metrics_summary) + }, + ToolMetricSummary::Callgrind(metrics_summary) => { + parse_callgrind_metrics_summary(metrics_summary) + }, + ToolMetricSummary::Dhat(metrics_summary) => parse_dhat_metrics_summary(metrics_summary), + ToolMetricSummary::ErrorTool(metrics_summary) => match profile.tool { + ValgrindTool::Memcheck => parse_memcheck_metrics_summary(metrics_summary), + ValgrindTool::Helgrind => parse_helgind_metrics_summary(metrics_summary), + ValgrindTool::DRD => parse_drd_metrics_summary(metrics_summary), + // These other tools are no error tools and are already covered + ValgrindTool::Callgrind + | ValgrindTool::Cachegrind + | ValgrindTool::DHAT + // These tools don't have a metric output (covered by `ToolMetricSummary::None`) + | ValgrindTool::Massif + | ValgrindTool::BBV => vec![], + }, + ToolMetricSummary::None => vec![], + }) + .collect(); + + Some((name, measures)) +} + +fn parse_drd_metrics_summary(metrics_summary: MetricsSummary) -> Vec { + metrics_summary + .0 + .into_iter() + .filter_map(|(metric, diff)| diff_to_json(&diff).map(|json| (metric, json))) + .map(|(metric, json)| match metric { + ErrorMetric::Contexts => GungraunMeasure::DrdContexts(json), + ErrorMetric::Errors => GungraunMeasure::DrdErrors(json), + ErrorMetric::SuppressedContexts => GungraunMeasure::DrdSuppressedContexts(json), + ErrorMetric::SuppressedErrors => GungraunMeasure::DrdSuppressedErrors(json), + }) + .collect() +} + +fn parse_helgind_metrics_summary( + metrics_summary: MetricsSummary, +) -> Vec { + metrics_summary + .0 + .into_iter() + .filter_map(|(metric, diff)| diff_to_json(&diff).map(|json| (metric, json))) + .map(|(metric, json)| match metric { + ErrorMetric::Contexts => GungraunMeasure::HelgrindContexts(json), + ErrorMetric::Errors => GungraunMeasure::HelgrindErrors(json), + ErrorMetric::SuppressedContexts => GungraunMeasure::HelgrindSuppressedContexts(json), + ErrorMetric::SuppressedErrors => GungraunMeasure::HelgrindSuppressedErrors(json), + }) + .collect() +} + +fn parse_memcheck_metrics_summary( + metrics_summary: MetricsSummary, +) -> Vec { + metrics_summary + .0 + .into_iter() + .filter_map(|(metric, diff)| diff_to_json(&diff).map(|json| (metric, json))) + .map(|(metric, json)| match metric { + ErrorMetric::Contexts => GungraunMeasure::MemcheckContexts(json), + ErrorMetric::Errors => GungraunMeasure::MemcheckErrors(json), + ErrorMetric::SuppressedContexts => GungraunMeasure::MemcheckSuppressedContexts(json), + ErrorMetric::SuppressedErrors => GungraunMeasure::MemcheckSuppressedErrors(json), + }) + .collect() +} + +fn parse_callgrind_metrics_summary( + metrics_summary: MetricsSummary, +) -> Vec { + metrics_summary + .0 + .into_iter() + .filter_map(|(event_kind, diff)| diff_to_json(&diff).map(|json| (event_kind, json))) + .map(|(event_kind, json)| match event_kind { + EventKind::AcCost1 => GungraunMeasure::L1BadTemporalLocality(json), + EventKind::AcCost2 => GungraunMeasure::LLBadTemporalLocality(json), + EventKind::Bc => GungraunMeasure::ExecutedConditionalBranches(json), + EventKind::Bcm => GungraunMeasure::MispredictedConditionalBranches(json), + EventKind::Bi => GungraunMeasure::ExecutedIndirectBranches(json), + EventKind::Bim => GungraunMeasure::MispredictedIndirectBranches(json), + EventKind::D1MissRate => GungraunMeasure::L1DataCacheMissRate(json), + EventKind::D1mr => GungraunMeasure::L1DataCacheReadMisses(json), + EventKind::D1mw => GungraunMeasure::L1DataCacheWriteMisses(json), + EventKind::DLdmr => GungraunMeasure::DirtyMissDataRead(json), + EventKind::DLdmw => GungraunMeasure::DirtyMissDataWrite(json), + EventKind::DLmr => GungraunMeasure::LLDataCacheReadMisses(json), + EventKind::DLmw => GungraunMeasure::LLDataCacheWriteMisses(json), + EventKind::Dr => GungraunMeasure::DataCacheReads(json), + EventKind::Dw => GungraunMeasure::DataCacheWrites(json), + EventKind::EstimatedCycles => GungraunMeasure::EstimatedCycles(json), + EventKind::Ge => GungraunMeasure::GlobalBusEvents(json), + EventKind::I1MissRate => GungraunMeasure::L1InstrCacheMissRate(json), + EventKind::I1mr => GungraunMeasure::L1InstrCacheReadMisses(json), + EventKind::ILdmr => GungraunMeasure::DirtyMissInstructionRead(json), + EventKind::ILmr => GungraunMeasure::LLInstrCacheReadMisses(json), + EventKind::Ir => GungraunMeasure::Instructions(json), + EventKind::L1HitRate => GungraunMeasure::L1HitRate(json), + EventKind::L1hits => GungraunMeasure::L1Hits(json), + EventKind::LLHitRate => GungraunMeasure::LLHitRate(json), + EventKind::LLMissRate => GungraunMeasure::LLCacheMissRate(json), + EventKind::LLdMissRate => GungraunMeasure::LLDataCacheMissRate(json), + EventKind::LLhits => GungraunMeasure::LLHits(json), + EventKind::LLiMissRate => GungraunMeasure::LLInstrCacheMissRate(json), + EventKind::RamHitRate => GungraunMeasure::RamHitRate(json), + EventKind::RamHits => GungraunMeasure::RamHits(json), + EventKind::SpLoss1 => GungraunMeasure::L1BadSpatialLocality(json), + EventKind::SpLoss2 => GungraunMeasure::LLBadSpatialLocality(json), + EventKind::SysCount => GungraunMeasure::NumberSystemCalls(json), + EventKind::SysCpuTime => GungraunMeasure::CpuTimeSystemCalls(json), + EventKind::SysTime => GungraunMeasure::TimeSystemCalls(json), + EventKind::TotalRW => GungraunMeasure::TotalReadWrite(json), + }) + .collect() +} + +fn parse_cachegrind_metrics_summary( + metrics_summary: MetricsSummary, +) -> Vec { + metrics_summary + .0 + .into_iter() + .filter_map(|(metric, diff)| diff_to_json(&diff).map(|json| (metric, json))) + .map(|(metric, json)| match metric { + CachegrindMetric::Bc => GungraunMeasure::ExecutedConditionalBranches(json), + CachegrindMetric::Bcm => GungraunMeasure::MispredictedConditionalBranches(json), + CachegrindMetric::Bi => GungraunMeasure::ExecutedIndirectBranches(json), + CachegrindMetric::Bim => GungraunMeasure::MispredictedIndirectBranches(json), + CachegrindMetric::D1MissRate => GungraunMeasure::L1DataCacheMissRate(json), + CachegrindMetric::D1mr => GungraunMeasure::L1DataCacheReadMisses(json), + CachegrindMetric::D1mw => GungraunMeasure::L1DataCacheWriteMisses(json), + CachegrindMetric::DLmr => GungraunMeasure::LLDataCacheReadMisses(json), + CachegrindMetric::DLmw => GungraunMeasure::LLDataCacheWriteMisses(json), + CachegrindMetric::Dr => GungraunMeasure::DataCacheReads(json), + CachegrindMetric::Dw => GungraunMeasure::DataCacheWrites(json), + CachegrindMetric::EstimatedCycles => GungraunMeasure::EstimatedCycles(json), + CachegrindMetric::I1MissRate => GungraunMeasure::L1InstrCacheMissRate(json), + CachegrindMetric::I1mr => GungraunMeasure::L1InstrCacheReadMisses(json), + CachegrindMetric::ILmr => GungraunMeasure::LLInstrCacheReadMisses(json), + CachegrindMetric::Ir => GungraunMeasure::Instructions(json), + CachegrindMetric::L1HitRate => GungraunMeasure::L1HitRate(json), + CachegrindMetric::L1hits => GungraunMeasure::L1Hits(json), + CachegrindMetric::LLHitRate => GungraunMeasure::LLHitRate(json), + CachegrindMetric::LLMissRate => GungraunMeasure::LLCacheMissRate(json), + CachegrindMetric::LLdMissRate => GungraunMeasure::LLDataCacheMissRate(json), + CachegrindMetric::LLhits => GungraunMeasure::LLHits(json), + CachegrindMetric::LLiMissRate => GungraunMeasure::LLInstrCacheMissRate(json), + CachegrindMetric::RamHitRate => GungraunMeasure::RamHitRate(json), + CachegrindMetric::RamHits => GungraunMeasure::RamHits(json), + CachegrindMetric::TotalRW => GungraunMeasure::TotalReadWrite(json), + }) + .collect() +} + +fn parse_dhat_metrics_summary(metrics_summary: MetricsSummary) -> Vec { + metrics_summary + .0 + .into_iter() + .filter_map(|(metric, diff)| diff_to_json(&diff).map(|json| (metric, json))) + .map(|(metric, json)| match metric { + DhatMetric::AtTEndBlocks => GungraunMeasure::AtTEndBlocks(json), + DhatMetric::AtTEndBytes => GungraunMeasure::AtTEndBytes(json), + DhatMetric::AtTGmaxBlocks => GungraunMeasure::AtTGmaxBlocks(json), + DhatMetric::AtTGmaxBytes => GungraunMeasure::AtTGmaxBytes(json), + DhatMetric::MaximumBlocks => GungraunMeasure::MaximumBlocks(json), + DhatMetric::MaximumBytes => GungraunMeasure::MaximumBytes(json), + DhatMetric::ReadsBytes => GungraunMeasure::ReadsBytes(json), + DhatMetric::TotalBlocks => GungraunMeasure::TotalBlocks(json), + DhatMetric::TotalBytes => GungraunMeasure::TotalBytes(json), + DhatMetric::TotalEvents => GungraunMeasure::TotalEvents(json), + DhatMetric::TotalLifetimes => GungraunMeasure::TotalLifetimes(json), + DhatMetric::TotalUnits => GungraunMeasure::TotalUnits(json), + DhatMetric::WritesBytes => GungraunMeasure::WritesBytes(json), + }) + .collect() +} + +fn diff_to_json(diff: &MetricsDiff) -> Option { + let metric = match diff.metrics { + EitherOrBoth::Left(new) | EitherOrBoth::Both(new, _) => new, + EitherOrBoth::Right(_) => return None, + }; + + #[expect( + clippy::cast_precision_loss, + reason = "bencher metrics have f64 precision" + )] + let value = match metric { + Metric::Int(int) => int as f64, + Metric::Float(float) => float, + }; + + Some(JsonNewMetric { + value: value.into(), + lower_value: None, + upper_value: None, + }) +} diff --git a/lib/bencher_adapter/src/adapters/rust/mod.rs b/lib/bencher_adapter/src/adapters/rust/mod.rs index 29bea2c2b..11216840f 100644 --- a/lib/bencher_adapter/src/adapters/rust/mod.rs +++ b/lib/bencher_adapter/src/adapters/rust/mod.rs @@ -1,9 +1,13 @@ pub mod bench; pub mod criterion; pub mod gungraun; +pub mod gungraun_json; pub mod iai; -use self::{criterion::AdapterRustCriterion, gungraun::AdapterRustGungraun, iai::AdapterRustIai}; +use self::{ + criterion::AdapterRustCriterion, gungraun::AdapterRustGungraun, + gungraun_json::AdapterRustGungraunJson, iai::AdapterRustIai, +}; use crate::{Adaptable, AdapterResults, Settings}; use bench::AdapterRustBench; @@ -15,6 +19,7 @@ impl Adaptable for AdapterRust { .or_else(|| AdapterRustCriterion::parse(input, settings)) .or_else(|| AdapterRustIai::parse(input, settings)) .or_else(|| AdapterRustGungraun::parse(input, settings)) + .or_else(|| AdapterRustGungraunJson::parse(input, settings)) } } From 56cd044182163b5b17f39f2a76fb7e4f95b7a18e Mon Sep 17 00:00:00 2001 From: gamma0987 Date: Sat, 8 Aug 2026 15:53:09 +0200 Subject: [PATCH 03/11] Register rust_gungraun_json adapter --- lib/bencher_adapter/src/lib.rs | 3 ++- lib/bencher_json/src/project/report.rs | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/bencher_adapter/src/lib.rs b/lib/bencher_adapter/src/lib.rs index 193c3fafd..c96e25781 100644 --- a/lib/bencher_adapter/src/lib.rs +++ b/lib/bencher_adapter/src/lib.rs @@ -18,7 +18,7 @@ use adapters::{ ruby::{AdapterRuby, benchmark::AdapterRubyBenchmark}, rust::{ AdapterRust, bench::AdapterRustBench, criterion::AdapterRustCriterion, - gungraun::AdapterRustGungraun, iai::AdapterRustIai, + gungraun::AdapterRustGungraun, gungraun_json::AdapterRustGungraunJson, iai::AdapterRustIai, }, shell::{AdapterShell, hyperfine::AdapterShellHyperfine}, }; @@ -65,6 +65,7 @@ impl Adaptable for Adapter { Adapter::RustCriterion => AdapterRustCriterion::parse(input, settings), Adapter::RustIai => AdapterRustIai::parse(input, settings), Adapter::RustGungraun => AdapterRustGungraun::parse(input, settings), + Adapter::RustGungraunJson => AdapterRustGungraunJson::parse(input, settings), Adapter::Shell => AdapterShell::parse(input, settings), Adapter::ShellHyperfine => AdapterShellHyperfine::parse(input, settings), } diff --git a/lib/bencher_json/src/project/report.rs b/lib/bencher_json/src/project/report.rs index 3f33d6267..1a256f7d2 100644 --- a/lib/bencher_json/src/project/report.rs +++ b/lib/bencher_json/src/project/report.rs @@ -90,6 +90,7 @@ const RUST_BENCH_INT: i32 = 21; const RUST_CRITERION_INT: i32 = 22; const RUST_IAI_INT: i32 = 23; const RUST_GUNGRAUN_INT: i32 = 24; +const RUST_GUNGRAUN_JSON_INT: i32 = 25; const CPP_INT: i32 = 30; const CPP_GOOGLE_INT: i32 = 31; const CPP_CATCH2_INT: i32 = 32; @@ -132,6 +133,7 @@ pub enum Adapter { // https://github.com/bencherdev/bencher/issues/619 #[serde(alias = "rust_iai_callgrind")] RustGungraun = RUST_GUNGRAUN_INT, + RustGungraunJson = RUST_GUNGRAUN_JSON_INT, Cpp = CPP_INT, CppGoogle = CPP_GOOGLE_INT, CppCatch2 = CPP_CATCH2_INT, @@ -179,6 +181,7 @@ impl Adapter { | Self::RustCriterion | Self::RustIai | Self::RustGungraun + | Self::RustGungraunJson | Self::CppGoogle | Self::CppCatch2 | Self::GoBench @@ -206,6 +209,7 @@ impl fmt::Display for Adapter { Self::RustCriterion => write!(f, "rust_criterion"), Self::RustIai => write!(f, "rust_iai"), Self::RustGungraun => write!(f, "rust_gungraun"), + Self::RustGungraunJson => write!(f, "rust_gungraun_json"), Self::Cpp => write!(f, "cpp"), Self::CppGoogle => write!(f, "cpp_google"), Self::CppCatch2 => write!(f, "cpp_catch2"), @@ -239,8 +243,8 @@ mod adapter { DART_BENCHMARK_HARNESS_INT, DART_INT, GO_BENCH_INT, GO_INT, JAVA_INT, JAVA_JMH_INT, JS_BENCHMARK_INT, JS_INT, JS_TIME_INT, JS_VITEST_INT, JSON_INT, MAGIC_INT, PYTHON_ASV_INT, PYTHON_INT, PYTHON_PYTEST_INT, RUBY_BENCHMARK_INT, RUBY_INT, RUST_BENCH_INT, - RUST_CRITERION_INT, RUST_GUNGRAUN_INT, RUST_IAI_INT, RUST_INT, SHELL_HYPERFINE_INT, - SHELL_INT, + RUST_CRITERION_INT, RUST_GUNGRAUN_INT, RUST_GUNGRAUN_JSON_INT, RUST_IAI_INT, RUST_INT, + SHELL_HYPERFINE_INT, SHELL_INT, }; #[derive(Debug, thiserror::Error)] @@ -266,6 +270,7 @@ mod adapter { Self::RustCriterion => RUST_CRITERION_INT.to_sql(out), Self::RustIai => RUST_IAI_INT.to_sql(out), Self::RustGungraun => RUST_GUNGRAUN_INT.to_sql(out), + Self::RustGungraunJson => RUST_GUNGRAUN_JSON_INT.to_sql(out), Self::Cpp => CPP_INT.to_sql(out), Self::CppGoogle => CPP_GOOGLE_INT.to_sql(out), Self::CppCatch2 => CPP_CATCH2_INT.to_sql(out), From d08cfab8bc30792d5df9e3f211fea76443b3976f Mon Sep 17 00:00:00 2001 From: gamma0987 Date: Sat, 8 Aug 2026 20:40:18 +0200 Subject: [PATCH 04/11] Add tests for gungraun json parser --- .../src/adapters/rust/gungraun_json.rs | 368 ++++++++++++++++++ lib/bencher_adapter/src/adapters/rust/mod.rs | 13 +- .../gungraun/json_multiple_benchmarks.txt | 17 + .../rust/gungraun/json_multiple_tools.txt | 16 + .../rust/gungraun/json_no_id_no_details.txt | 14 + .../tool_output/rust/gungraun/json_not_v6.txt | 14 + .../json_one_cachegrind_all_metrics.txt | 16 + .../json_one_callgrind_all_metrics.txt | 15 + .../rust/gungraun/json_one_callgrind_diff.txt | 14 + .../json_one_callgrind_no_diff_new.txt | 14 + .../json_one_callgrind_no_diff_old.txt | 14 + .../gungraun/json_one_dhat_all_metrics.txt | 17 + .../gungraun/json_one_drd_all_metrics.txt | 19 + .../json_one_helgrind_all_metrics.txt | 19 + .../json_one_memcheck_all_metrics.txt | 19 + .../json_one_tool_without_metrics.txt | 17 + 16 files changed, 605 insertions(+), 1 deletion(-) create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_multiple_benchmarks.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_multiple_tools.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_no_id_no_details.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_not_v6.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_one_cachegrind_all_metrics.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_all_metrics.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_diff.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_no_diff_new.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_no_diff_old.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_one_dhat_all_metrics.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_one_drd_all_metrics.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_one_helgrind_all_metrics.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_one_memcheck_all_metrics.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_one_tool_without_metrics.txt diff --git a/lib/bencher_adapter/src/adapters/rust/gungraun_json.rs b/lib/bencher_adapter/src/adapters/rust/gungraun_json.rs index efe1292fe..59f06d832 100644 --- a/lib/bencher_adapter/src/adapters/rust/gungraun_json.rs +++ b/lib/bencher_adapter/src/adapters/rust/gungraun_json.rs @@ -262,3 +262,371 @@ fn diff_to_json(diff: &MetricsDiff) -> Option { upper_value: None, }) } + +#[cfg(test)] +pub(crate) mod test_rust_gungraun_json { + use crate::{ + AdapterResults, Settings, + adapters::test_util::{convert_file_path, opt_convert_file_path}, + }; + use bencher_json::project::measure::built_in::{BuiltInMeasure as _, gungraun::*}; + use ordered_float::OrderedFloat; + use pretty_assertions::assert_eq; + + use super::AdapterRustGungraunJson; + use std::collections::HashMap; + + #[test] + fn not_v6() { + let results = opt_convert_file_path::( + "./tool_output/rust/gungraun/json_not_v6.txt", + Settings::default(), + ); + + assert!(results.is_none()); + } + + #[test] + fn no_id_no_details() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_no_id_no_details.txt", + ); + + let expected = HashMap::from([(D1MissRate::SLUG_STR, 0.1), (D1mr::SLUG_STR, 6.0)]); + + assert_eq!(results.inner.len(), 1); + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100", + ); + } + + #[test] + fn one_callgrind_diff() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_callgrind_diff.txt", + ); + + validate_adapter_rust_gungraun_json(&results); + } + + #[test] + fn one_callgrind_no_diff_new() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_callgrind_no_diff_new.txt", + ); + + validate_adapter_rust_gungraun_json(&results); + } + + #[test] + fn one_callgrind_no_diff_old() { + let expected = HashMap::new(); + + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_callgrind_no_diff_old.txt", + ); + + assert_eq!(results.inner.len(), 1); + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::some_id", + ); + } + + #[test] + fn one_callgrind_all_metrics() { + let expected = HashMap::from([ + (AcCost1::SLUG_STR, 0.0), + (AcCost2::SLUG_STR, 100.0), + (Bc::SLUG_STR, 200.0), + (Bcm::SLUG_STR, 300.0), + (Bi::SLUG_STR, 400.0), + (Bim::SLUG_STR, 500.0), + (D1MissRate::SLUG_STR, 0.0), + (D1mr::SLUG_STR, 600.0), + (D1mw::SLUG_STR, 700.0), + (DLdmr::SLUG_STR, 800.0), + (DLdmw::SLUG_STR, 900.0), + (DLmr::SLUG_STR, 1000.0), + (DLmw::SLUG_STR, 1100.0), + (Dr::SLUG_STR, 1200.0), + (Dw::SLUG_STR, 1300.0), + (EstimatedCycles::SLUG_STR, 1400.0), + (GlobalBusEvents::SLUG_STR, 1500.0), + (I1MissRate::SLUG_STR, 0.1), + (I1mr::SLUG_STR, 1600.0), + (ILdmr::SLUG_STR, 1700.0), + (ILmr::SLUG_STR, 1800.0), + (Instructions::SLUG_STR, 1900.0), + (L1HitRate::SLUG_STR, 0.2), + (L1Hits::SLUG_STR, 2000.0), + (LLHitRate::SLUG_STR, 0.3), + (LLMissRate::SLUG_STR, 0.4), + (LLdMissRate::SLUG_STR, 0.5), + (LLHits::SLUG_STR, 2100.0), + (LLiMissRate::SLUG_STR, 0.6), + (RamHitRate::SLUG_STR, 0.7), + (RamHits::SLUG_STR, 2200.0), + (SpLoss1::SLUG_STR, 2300.0), + (SpLoss2::SLUG_STR, 2400.0), + (SysCount::SLUG_STR, 2500.0), + (SysCpuTime::SLUG_STR, 2600.0), + (SysTime::SLUG_STR, 2700.0), + (TotalReadWrite::SLUG_STR, 2800.0), + ]); + + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_callgrind_all_metrics.txt", + ); + + assert_eq!(results.inner.len(), 1); + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::some_id", + ); + } + + #[test] + fn one_cachegrind_all_metrics() { + let expected = HashMap::from([ + (Bc::SLUG_STR, 0.0), + (Bcm::SLUG_STR, 100.0), + (Bi::SLUG_STR, 200.0), + (Bim::SLUG_STR, 300.0), + (D1MissRate::SLUG_STR, 0.0), + (D1mr::SLUG_STR, 400.0), + (D1mw::SLUG_STR, 500.0), + (DLmr::SLUG_STR, 600.0), + (DLmw::SLUG_STR, 700.0), + (Dr::SLUG_STR, 800.0), + (Dw::SLUG_STR, 900.0), + (EstimatedCycles::SLUG_STR, 1000.0), + (I1MissRate::SLUG_STR, 0.1), + (I1mr::SLUG_STR, 1100.0), + (ILmr::SLUG_STR, 1200.0), + (Instructions::SLUG_STR, 1300.0), + (L1HitRate::SLUG_STR, 0.2), + (L1Hits::SLUG_STR, 1400.0), + (LLHitRate::SLUG_STR, 0.3), + (LLMissRate::SLUG_STR, 0.4), + (LLdMissRate::SLUG_STR, 0.5), + (LLHits::SLUG_STR, 1500.0), + (LLiMissRate::SLUG_STR, 0.6), + (RamHitRate::SLUG_STR, 0.7), + (RamHits::SLUG_STR, 1600.0), + (TotalReadWrite::SLUG_STR, 1700.0), + ]); + + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_cachegrind_all_metrics.txt", + ); + + assert_eq!(results.inner.len(), 1); + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::some_id", + ); + } + + #[test] + fn one_dhat_all_metrics() { + let expected = HashMap::from([ + (AtTEndBlocks::SLUG_STR, 0.0), + (AtTEndBytes::SLUG_STR, 1.0), + (AtTGmaxBlocks::SLUG_STR, 2.0), + (AtTGmaxBytes::SLUG_STR, 3.0), + (MaximumBlocks::SLUG_STR, 4.0), + (MaximumBytes::SLUG_STR, 5.0), + (ReadsBytes::SLUG_STR, 6.0), + (TotalBlocks::SLUG_STR, 7.0), + (TotalBytes::SLUG_STR, 8.0), + (TotalEvents::SLUG_STR, 9.0), + (TotalLifetimes::SLUG_STR, 10.0), + (TotalUnits::SLUG_STR, 11.0), + (WritesBytes::SLUG_STR, 12.0), + ]); + + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_dhat_all_metrics.txt", + ); + + assert_eq!(results.inner.len(), 1); + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::some_id", + ); + } + + #[test] + fn one_memcheck_all_metrics() { + let expected = HashMap::from([ + (MemcheckContexts::SLUG_STR, 0.0), + (MemcheckErrors::SLUG_STR, 1.0), + (MemcheckSuppressedContexts::SLUG_STR, 2.0), + (MemcheckSuppressedErrors::SLUG_STR, 3.0), + ]); + + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_memcheck_all_metrics.txt", + ); + + assert_eq!(results.inner.len(), 1); + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::some_id", + ); + } + + #[test] + fn one_helgrind_all_metrics() { + let expected = HashMap::from([ + (HelgrindContexts::SLUG_STR, 0.0), + (HelgrindErrors::SLUG_STR, 1.0), + (HelgrindSuppressedContexts::SLUG_STR, 2.0), + (HelgrindSuppressedErrors::SLUG_STR, 3.0), + ]); + + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_helgrind_all_metrics.txt", + ); + + assert_eq!(results.inner.len(), 1); + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::some_id", + ); + } + + #[test] + fn one_drd_all_metrics() { + let expected = HashMap::from([ + (DrdContexts::SLUG_STR, 0.0), + (DrdErrors::SLUG_STR, 1.0), + (DrdSuppressedContexts::SLUG_STR, 2.0), + (DrdSuppressedErrors::SLUG_STR, 3.0), + ]); + + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_drd_all_metrics.txt", + ); + + assert_eq!(results.inner.len(), 1); + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::some_id", + ); + } + + #[test] + fn one_tool_without_metrics() { + let expected = HashMap::new(); + + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_tool_without_metrics.txt", + ); + + assert_eq!(results.inner.len(), 1); + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::some_id", + ); + } + + #[test] + fn multiple_tools() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_multiple_tools.txt", + ); + + let expected = HashMap::from([ + // Callgrid + (D1MissRate::SLUG_STR, 0.1), + (D1mr::SLUG_STR, 6.0), + // DHAT + (AtTEndBlocks::SLUG_STR, 1.0), + ]); + + assert_eq!(results.inner.len(), 1); + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::some_id", + ); + } + + #[test] + fn multiple_benchmarks() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_multiple_benchmarks.txt", + ); + + assert_eq!(results.inner.len(), 2); + + { + let expected = HashMap::from([ + // Callgrid + (D1MissRate::SLUG_STR, 0.1), + (D1mr::SLUG_STR, 6.0), + // DHAT + (AtTEndBlocks::SLUG_STR, 1.0), + ]); + + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::first_id", + ); + } + { + let expected = HashMap::from([ + (MemcheckContexts::SLUG_STR, 0.0), + (MemcheckErrors::SLUG_STR, 1.0), + (MemcheckSuppressedContexts::SLUG_STR, 2.0), + (MemcheckSuppressedErrors::SLUG_STR, 3.0), + ]); + + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::second_id", + ); + } + } + + pub fn validate_adapter_rust_gungraun_json(results: &AdapterResults) { + let expected = HashMap::from([(D1MissRate::SLUG_STR, 0.1), (D1mr::SLUG_STR, 6.0)]); + + assert_eq!(results.inner.len(), 1); + compare_benchmark( + &expected, + results, + "play_game::bench_play_game_group::bench_play_game_100::some_id", + ); + } + + fn compare_benchmark( + expected: &HashMap<&str, f64>, + results: &AdapterResults, + benchmark_name: &str, + ) { + let actual = results.get(benchmark_name).unwrap(); + assert_eq!(actual.inner.len(), expected.len()); + + for (key, value) in expected { + let metric = actual.get(key).unwrap(); + assert_eq!(metric.value, OrderedFloat::from(*value)); + assert_eq!(metric.lower_value, None); + assert_eq!(metric.upper_value, None); + } + } +} diff --git a/lib/bencher_adapter/src/adapters/rust/mod.rs b/lib/bencher_adapter/src/adapters/rust/mod.rs index 11216840f..3acc1d422 100644 --- a/lib/bencher_adapter/src/adapters/rust/mod.rs +++ b/lib/bencher_adapter/src/adapters/rust/mod.rs @@ -29,7 +29,7 @@ mod test_rust { use crate::adapters::{ rust::{ bench::test_rust_bench, criterion::test_rust_criterion, gungraun::test_rust_gungraun, - iai::test_rust_iai, + gungraun_json::test_rust_gungraun_json, iai::test_rust_iai, }, test_util::convert_file_path, }; @@ -63,4 +63,15 @@ mod test_rust { &test_rust_gungraun::OptionalMetrics::default(), ); } + + #[test] + fn adapter_rust_gungraun_json() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_callgrind_diff.txt", + ); + + dbg!(&results); + + test_rust_gungraun_json::validate_adapter_rust_gungraun_json(&results); + } } diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_multiple_benchmarks.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_multiple_benchmarks.txt new file mode 100644 index 000000000..a4c8fff96 --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_multiple_benchmarks.txt @@ -0,0 +1,17 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":"first_id","kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/callgrind.bench_play_game_100.log"],"out_paths":["/callgrind.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Left":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/callgrind.bench_play_game_100.out","pid":12345,"thread":1}},"metrics_summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Float":0.1}}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Int":6}}}}}}],"total":{"regressions":[],"summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Float":0.1}}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Int":6}}}}}}},"tool":"Callgrind"},{"flamegraphs":[],"log_paths":["/dhat.bench_play_game_100.log"],"out_paths":["/dhat.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Right":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/dhat.bench_play_game_100.out","pid":12345,"thread":1}},"metrics_summary":{"Dhat":{"AtTEndBlocks":{"diffs":null,"metrics":{"Left":{"Int":1}}}}}}],"total":{"regressions":[],"summary":{"Dhat":{"AtTEndBlocks":{"diffs":null,"metrics":{"Left":{"Int":1}}}}}}},"tool":"DHAT"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":"second_id","kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/memcheck.bench_play_game_100.log"],"out_paths":["/memcheck.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Left":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":"HEAP SUMMARY:\n in use at exit: 544 bytes in 1 blocks\n total heap usage: 115 allocs, 114 frees, 3,255 bytes allocated\n\nLEAK SUMMARY:\n definitely lost: 0 bytes in 0 blocks\n indirectly lost: 0 bytes in 0 blocks\n possibly lost: 0 bytes in 0 blocks\n still reachable: 544 bytes in 1 blocks\n suppressed: 0 bytes in 0 blocks\nRerun with --leak-check=full to see details of leaked memory\n\nFor lists of detected and suppressed errors, rerun with: -s","parent_pid":12345,"part":null,"path":"/memcheck.bench_play_game_100.log","pid":23456,"thread":null}},"metrics_summary":{"ErrorTool":{"Contexts":{"diffs":null,"metrics":{"Left":{"Int":0}}},"Errors":{"diffs":null,"metrics":{"Left":{"Int":1}}},"SuppressedContexts":{"diffs":null,"metrics":{"Left":{"Int":2}}},"SuppressedErrors":{"diffs":null,"metrics":{"Left":{"Int":3}}}}}}],"total":{"regressions":[],"summary":{"ErrorTool":{"Contexts":{"diffs":null,"metrics":{"Left":{"Int":0}}},"Errors":{"diffs":null,"metrics":{"Left":{"Int":1}}},"SuppressedContexts":{"diffs":null,"metrics":{"Left":{"Int":2}}},"SuppressedErrors":{"diffs":null,"metrics":{"Left":{"Int":3}}}}}}},"tool":"Memcheck"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} + + + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_multiple_tools.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_multiple_tools.txt new file mode 100644 index 000000000..378807f28 --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_multiple_tools.txt @@ -0,0 +1,16 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":"some_id","kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/callgrind.bench_play_game_100.log"],"out_paths":["/callgrind.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Left":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/callgrind.bench_play_game_100.out","pid":12345,"thread":1}},"metrics_summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Float":0.1}}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Int":6}}}}}}],"total":{"regressions":[],"summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Float":0.1}}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Int":6}}}}}}},"tool":"Callgrind"},{"flamegraphs":[],"log_paths":["/dhat.bench_play_game_100.log"],"out_paths":["/dhat.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Right":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/dhat.bench_play_game_100.out","pid":12345,"thread":1}},"metrics_summary":{"Dhat":{"AtTEndBlocks":{"diffs":null,"metrics":{"Left":{"Int":1}}}}}}],"total":{"regressions":[],"summary":{"Dhat":{"AtTEndBlocks":{"diffs":null,"metrics":{"Left":{"Int":1}}}}}}},"tool":"DHAT"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} + + + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_no_id_no_details.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_no_id_no_details.txt new file mode 100644 index 000000000..67c150a55 --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_no_id_no_details.txt @@ -0,0 +1,14 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":null,"kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/callgrind.bench_play_game_100.log"],"out_paths":["/callgrind.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Both":[{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/callgrind.bench_play_game_100.out","pid":12345,"thread":1},{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/bencher/examples/rust/gungraun/target/gungraun/game/play_game/bench_play_game_group/bench_play_game_100/callgrind.bench_play_game_100.out.old","pid":23456,"thread":1}]},"metrics_summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Both":[{"Float":0.1},{"Float":0.1}]}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Both":[{"Int":6},{"Int":6}]}}}}}],"total":{"regressions":[],"summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Both":[{"Float":0.1},{"Float":0.1}]}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Both":[{"Int":6},{"Int":6}]}}}}}},"tool":"Callgrind"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_not_v6.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_not_v6.txt new file mode 100644 index 000000000..02c2d8f37 --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_not_v6.txt @@ -0,0 +1,14 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":null,"kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/callgrind.bench_play_game_100.log"],"out_paths":["/callgrind.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Both":[{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/callgrind.bench_play_game_100.out","pid":12345,"thread":1},{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/bencher/examples/rust/gungraun/target/gungraun/game/play_game/bench_play_game_group/bench_play_game_100/callgrind.bench_play_game_100.out.old","pid":23456,"thread":1}]},"metrics_summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Both":[{"Float":0.1},{"Float":0.1}]}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Both":[{"Int":6},{"Int":6}]}}}}}],"total":{"regressions":[],"summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Both":[{"Float":0.1},{"Float":0.1}]}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Both":[{"Int":6},{"Int":6}]}}}}}},"tool":"Callgrind"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"5"} + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_one_cachegrind_all_metrics.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_cachegrind_all_metrics.txt new file mode 100644 index 000000000..14841b66c --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_cachegrind_all_metrics.txt @@ -0,0 +1,16 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":"some_id","kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/cachegrind.bench_play_game_100.log"],"out_paths":["/cachegrind.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Left":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/cachegrind.bench_play_game_100.out","pid":12345,"thread":1}},"metrics_summary":{"Cachegrind":{"Bc":{"diffs":null,"metrics":{"Left":{"Int":0}}},"Bcm":{"diffs":null,"metrics":{"Left":{"Int":100}}},"Bi":{"diffs":null,"metrics":{"Left":{"Int":200}}},"Bim":{"diffs":null,"metrics":{"Left":{"Int":300}}},"D1MissRate":{"diffs":null,"metrics":{"Left":{"Float":0.0}}},"D1mr":{"diffs":null,"metrics":{"Left":{"Int":400}}},"D1mw":{"diffs":null,"metrics":{"Left":{"Int":500}}},"DLmr":{"diffs":null,"metrics":{"Left":{"Int":600}}},"DLmw":{"diffs":null,"metrics":{"Left":{"Int":700}}},"Dr":{"diffs":null,"metrics":{"Left":{"Int":800}}},"Dw":{"diffs":null,"metrics":{"Left":{"Int":900}}},"EstimatedCycles":{"diffs":null,"metrics":{"Left":{"Int":1000}}},"I1MissRate":{"diffs":null,"metrics":{"Left":{"Float":0.1}}},"I1mr":{"diffs":null,"metrics":{"Left":{"Int":1100}}},"ILmr":{"diffs":null,"metrics":{"Left":{"Int":1200}}},"Ir":{"diffs":null,"metrics":{"Left":{"Int":1300}}},"L1HitRate":{"diffs":null,"metrics":{"Left":{"Float":0.2}}},"L1hits":{"diffs":null,"metrics":{"Left":{"Int":1400}}},"LLHitRate":{"diffs":null,"metrics":{"Left":{"Float":0.3}}},"LLMissRate":{"diffs":null,"metrics":{"Left":{"Float":0.4}}},"LLdMissRate":{"diffs":null,"metrics":{"Left":{"Float":0.5}}},"LLhits":{"diffs":null,"metrics":{"Left":{"Int":1500}}},"LLiMissRate":{"diffs":null,"metrics":{"Left":{"Float":0.6}}},"RamHitRate":{"diffs":null,"metrics":{"Left":{"Float":0.7}}},"RamHits":{"diffs":null,"metrics":{"Left":{"Int":1600}}},"TotalRW":{"diffs":null,"metrics":{"Left":{"Int":1700}}}}}}],"total":{"regressions":[],"summary":{"Cachegrind":{"Bc":{"diffs":null,"metrics":{"Left":{"Int":0}}},"Bcm":{"diffs":null,"metrics":{"Left":{"Int":100}}},"Bi":{"diffs":null,"metrics":{"Left":{"Int":200}}},"Bim":{"diffs":null,"metrics":{"Left":{"Int":300}}},"D1MissRate":{"diffs":null,"metrics":{"Left":{"Float":0.0}}},"D1mr":{"diffs":null,"metrics":{"Left":{"Int":400}}},"D1mw":{"diffs":null,"metrics":{"Left":{"Int":500}}},"DLmr":{"diffs":null,"metrics":{"Left":{"Int":600}}},"DLmw":{"diffs":null,"metrics":{"Left":{"Int":700}}},"Dr":{"diffs":null,"metrics":{"Left":{"Int":800}}},"Dw":{"diffs":null,"metrics":{"Left":{"Int":900}}},"EstimatedCycles":{"diffs":null,"metrics":{"Left":{"Int":1000}}},"I1MissRate":{"diffs":null,"metrics":{"Left":{"Float":0.1}}},"I1mr":{"diffs":null,"metrics":{"Left":{"Int":1100}}},"ILmr":{"diffs":null,"metrics":{"Left":{"Int":1200}}},"Ir":{"diffs":null,"metrics":{"Left":{"Int":1300}}},"L1HitRate":{"diffs":null,"metrics":{"Left":{"Float":0.2}}},"L1hits":{"diffs":null,"metrics":{"Left":{"Int":1400}}},"LLHitRate":{"diffs":null,"metrics":{"Left":{"Float":0.3}}},"LLMissRate":{"diffs":null,"metrics":{"Left":{"Float":0.4}}},"LLdMissRate":{"diffs":null,"metrics":{"Left":{"Float":0.5}}},"LLhits":{"diffs":null,"metrics":{"Left":{"Int":1500}}},"LLiMissRate":{"diffs":null,"metrics":{"Left":{"Float":0.6}}},"RamHitRate":{"diffs":null,"metrics":{"Left":{"Float":0.7}}},"RamHits":{"diffs":null,"metrics":{"Left":{"Int":1600}}},"TotalRW":{"diffs":null,"metrics":{"Left":{"Int":1700}}}}}}},"tool":"Cachegrind"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} + + + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_all_metrics.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_all_metrics.txt new file mode 100644 index 000000000..2b669fc31 --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_all_metrics.txt @@ -0,0 +1,15 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":"some_id","kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/callgrind.bench_play_game_100.log"],"out_paths":["/callgrind.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Left":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/callgrind.bench_play_game_100.out","pid":12345,"thread":1}},"metrics_summary":{"Callgrind":{"AcCost1":{"diffs":null,"metrics":{"Left":{"Int":0}}},"AcCost2":{"diffs":null,"metrics":{"Left":{"Int":100}}},"Bc":{"diffs":null,"metrics":{"Left":{"Int":200}}},"Bcm":{"diffs":null,"metrics":{"Left":{"Int":300}}},"Bi":{"diffs":null,"metrics":{"Left":{"Int":400}}},"Bim":{"diffs":null,"metrics":{"Left":{"Int":500}}},"D1MissRate":{"diffs":null,"metrics":{"Left":{"Float":0.0}}},"D1mr":{"diffs":null,"metrics":{"Left":{"Int":600}}},"D1mw":{"diffs":null,"metrics":{"Left":{"Int":700}}},"DLdmr":{"diffs":null,"metrics":{"Left":{"Int":800}}},"DLdmw":{"diffs":null,"metrics":{"Left":{"Int":900}}},"DLmr":{"diffs":null,"metrics":{"Left":{"Int":1000}}},"DLmw":{"diffs":null,"metrics":{"Left":{"Int":1100}}},"Dr":{"diffs":null,"metrics":{"Left":{"Int":1200}}},"Dw":{"diffs":null,"metrics":{"Left":{"Int":1300}}},"EstimatedCycles":{"diffs":null,"metrics":{"Left":{"Int":1400}}},"Ge":{"diffs":null,"metrics":{"Left":{"Int":1500}}},"I1MissRate":{"diffs":null,"metrics":{"Left":{"Float":0.1}}},"I1mr":{"diffs":null,"metrics":{"Left":{"Int":1600}}},"ILdmr":{"diffs":null,"metrics":{"Left":{"Int":1700}}},"ILmr":{"diffs":null,"metrics":{"Left":{"Int":1800}}},"Ir":{"diffs":null,"metrics":{"Left":{"Int":1900}}},"L1HitRate":{"diffs":null,"metrics":{"Left":{"Float":0.2}}},"L1hits":{"diffs":null,"metrics":{"Left":{"Int":2000}}},"LLHitRate":{"diffs":null,"metrics":{"Left":{"Float":0.3}}},"LLMissRate":{"diffs":null,"metrics":{"Left":{"Float":0.4}}},"LLdMissRate":{"diffs":null,"metrics":{"Left":{"Float":0.5}}},"LLhits":{"diffs":null,"metrics":{"Left":{"Int":2100}}},"LLiMissRate":{"diffs":null,"metrics":{"Left":{"Float":0.6}}},"RamHitRate":{"diffs":null,"metrics":{"Left":{"Float":0.7}}},"RamHits":{"diffs":null,"metrics":{"Left":{"Int":2200}}},"SpLoss1":{"diffs":null,"metrics":{"Left":{"Int":2300}}},"SpLoss2":{"diffs":null,"metrics":{"Left":{"Int":2400}}},"SysCount":{"diffs":null,"metrics":{"Left":{"Int":2500}}},"SysCpuTime":{"diffs":null,"metrics":{"Left":{"Int":2600}}},"SysTime":{"diffs":null,"metrics":{"Left":{"Int":2700}}},"TotalRW":{"diffs":null,"metrics":{"Left":{"Int":2800}}}}}}],"total":{"regressions":[],"summary":{"Callgrind":{"AcCost1":{"diffs":null,"metrics":{"Left":{"Int":0}}},"AcCost2":{"diffs":null,"metrics":{"Left":{"Int":100}}},"Bc":{"diffs":null,"metrics":{"Left":{"Int":200}}},"Bcm":{"diffs":null,"metrics":{"Left":{"Int":300}}},"Bi":{"diffs":null,"metrics":{"Left":{"Int":400}}},"Bim":{"diffs":null,"metrics":{"Left":{"Int":500}}},"D1MissRate":{"diffs":null,"metrics":{"Left":{"Float":0.0}}},"D1mr":{"diffs":null,"metrics":{"Left":{"Int":600}}},"D1mw":{"diffs":null,"metrics":{"Left":{"Int":700}}},"DLdmr":{"diffs":null,"metrics":{"Left":{"Int":800}}},"DLdmw":{"diffs":null,"metrics":{"Left":{"Int":900}}},"DLmr":{"diffs":null,"metrics":{"Left":{"Int":1000}}},"DLmw":{"diffs":null,"metrics":{"Left":{"Int":1100}}},"Dr":{"diffs":null,"metrics":{"Left":{"Int":1200}}},"Dw":{"diffs":null,"metrics":{"Left":{"Int":1300}}},"EstimatedCycles":{"diffs":null,"metrics":{"Left":{"Int":1400}}},"Ge":{"diffs":null,"metrics":{"Left":{"Int":1500}}},"I1MissRate":{"diffs":null,"metrics":{"Left":{"Float":0.1}}},"I1mr":{"diffs":null,"metrics":{"Left":{"Int":1600}}},"ILdmr":{"diffs":null,"metrics":{"Left":{"Int":1700}}},"ILmr":{"diffs":null,"metrics":{"Left":{"Int":1800}}},"Ir":{"diffs":null,"metrics":{"Left":{"Int":1900}}},"L1HitRate":{"diffs":null,"metrics":{"Left":{"Float":0.2}}},"L1hits":{"diffs":null,"metrics":{"Left":{"Int":2000}}},"LLHitRate":{"diffs":null,"metrics":{"Left":{"Float":0.3}}},"LLMissRate":{"diffs":null,"metrics":{"Left":{"Float":0.4}}},"LLdMissRate":{"diffs":null,"metrics":{"Left":{"Float":0.5}}},"LLhits":{"diffs":null,"metrics":{"Left":{"Int":2100}}},"LLiMissRate":{"diffs":null,"metrics":{"Left":{"Float":0.6}}},"RamHitRate":{"diffs":null,"metrics":{"Left":{"Float":0.7}}},"RamHits":{"diffs":null,"metrics":{"Left":{"Int":2200}}},"SpLoss1":{"diffs":null,"metrics":{"Left":{"Int":2300}}},"SpLoss2":{"diffs":null,"metrics":{"Left":{"Int":2400}}},"SysCount":{"diffs":null,"metrics":{"Left":{"Int":2500}}},"SysCpuTime":{"diffs":null,"metrics":{"Left":{"Int":2600}}},"SysTime":{"diffs":null,"metrics":{"Left":{"Int":2700}}},"TotalRW":{"diffs":null,"metrics":{"Left":{"Int":2800}}}}}}},"tool":"Callgrind"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} + + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_diff.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_diff.txt new file mode 100644 index 000000000..36396d38c --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_diff.txt @@ -0,0 +1,14 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":"some_id","kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/callgrind.bench_play_game_100.log"],"out_paths":["/callgrind.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Both":[{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/callgrind.bench_play_game_100.out","pid":12345,"thread":1},{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/bencher/examples/rust/gungraun/target/gungraun/game/play_game/bench_play_game_group/bench_play_game_100/callgrind.bench_play_game_100.out.old","pid":23456,"thread":1}]},"metrics_summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Both":[{"Float":0.1},{"Float":0.1}]}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Both":[{"Int":6},{"Int":6}]}}}}}],"total":{"regressions":[],"summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Both":[{"Float":0.1},{"Float":0.1}]}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Both":[{"Int":6},{"Int":6}]}}}}}},"tool":"Callgrind"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_no_diff_new.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_no_diff_new.txt new file mode 100644 index 000000000..5a154c076 --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_no_diff_new.txt @@ -0,0 +1,14 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":"some_id","kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/callgrind.bench_play_game_100.log"],"out_paths":["/callgrind.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Left":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/callgrind.bench_play_game_100.out","pid":12345,"thread":1}},"metrics_summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Float":0.1}}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Int":6}}}}}}],"total":{"regressions":[],"summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Float":0.1}}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Int":6}}}}}}},"tool":"Callgrind"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_no_diff_old.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_no_diff_old.txt new file mode 100644 index 000000000..7c50bcc66 --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_callgrind_no_diff_old.txt @@ -0,0 +1,14 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":"some_id","kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/callgrind.bench_play_game_100.log"],"out_paths":["/callgrind.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Right":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/callgrind.bench_play_game_100.out","pid":12345,"thread":1}},"metrics_summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Right":{"Float":0.1}}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Right":{"Int":6}}}}}}],"total":{"regressions":[],"summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Right":{"Float":0.1}}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Right":{"Int":6}}}}}}},"tool":"Callgrind"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_one_dhat_all_metrics.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_dhat_all_metrics.txt new file mode 100644 index 000000000..56436ee40 --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_dhat_all_metrics.txt @@ -0,0 +1,17 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":"some_id","kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/dhat.bench_play_game_100.log"],"out_paths":["/dhat.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Right":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/dhat.bench_play_game_100.out","pid":12345,"thread":1}},"metrics_summary":{"Dhat":{"AtTEndBlocks":{"diffs":null,"metrics":{"Left":{"Int":0}}},"AtTEndBytes":{"diffs":null,"metrics":{"Left":{"Int":1}}},"AtTGmaxBlocks":{"diffs":null,"metrics":{"Left":{"Int":2}}},"AtTGmaxBytes":{"diffs":null,"metrics":{"Left":{"Int":3}}},"MaximumBlocks":{"diffs":null,"metrics":{"Left":{"Int":4}}},"MaximumBytes":{"diffs":null,"metrics":{"Left":{"Int":5}}},"ReadsBytes":{"diffs":null,"metrics":{"Left":{"Int":6}}},"TotalBlocks":{"diffs":null,"metrics":{"Left":{"Int":7}}},"TotalBytes":{"diffs":null,"metrics":{"Left":{"Int":8}}},"TotalEvents":{"diffs":null,"metrics":{"Left":{"Int":9}}},"TotalLifetimes":{"diffs":null,"metrics":{"Left":{"Int":10}}},"TotalUnits":{"diffs":null,"metrics":{"Left":{"Int":11}}},"WritesBytes":{"diffs":null,"metrics":{"Left":{"Int":12}}}}}}],"total":{"regressions":[],"summary":{"Dhat":{"AtTEndBlocks":{"diffs":null,"metrics":{"Left":{"Int":0}}},"AtTEndBytes":{"diffs":null,"metrics":{"Left":{"Int":1}}},"AtTGmaxBlocks":{"diffs":null,"metrics":{"Left":{"Int":2}}},"AtTGmaxBytes":{"diffs":null,"metrics":{"Left":{"Int":3}}},"MaximumBlocks":{"diffs":null,"metrics":{"Left":{"Int":4}}},"MaximumBytes":{"diffs":null,"metrics":{"Left":{"Int":5}}},"ReadsBytes":{"diffs":null,"metrics":{"Left":{"Int":6}}},"TotalBlocks":{"diffs":null,"metrics":{"Left":{"Int":7}}},"TotalBytes":{"diffs":null,"metrics":{"Left":{"Int":8}}},"TotalEvents":{"diffs":null,"metrics":{"Left":{"Int":9}}},"TotalLifetimes":{"diffs":null,"metrics":{"Left":{"Int":10}}},"TotalUnits":{"diffs":null,"metrics":{"Left":{"Int":11}}},"WritesBytes":{"diffs":null,"metrics":{"Left":{"Int":12}}}}}}},"tool":"DHAT"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} + + + + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_one_drd_all_metrics.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_drd_all_metrics.txt new file mode 100644 index 000000000..3aa2fc5de --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_drd_all_metrics.txt @@ -0,0 +1,19 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":"some_id","kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/drd.bench_play_game_100.log"],"out_paths":["/drd.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Left":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":12345,"part":null,"path":"/drd.bench_play_game_100.log","pid":23456,"thread":null}},"metrics_summary":{"ErrorTool":{"Contexts":{"diffs":null,"metrics":{"Left":{"Int":0}}},"Errors":{"diffs":null,"metrics":{"Left":{"Int":1}}},"SuppressedContexts":{"diffs":null,"metrics":{"Left":{"Int":2}}},"SuppressedErrors":{"diffs":null,"metrics":{"Left":{"Int":3}}}}}}],"total":{"regressions":[],"summary":{"ErrorTool":{"Contexts":{"diffs":null,"metrics":{"Left":{"Int":0}}},"Errors":{"diffs":null,"metrics":{"Left":{"Int":1}}},"SuppressedContexts":{"diffs":null,"metrics":{"Left":{"Int":2}}},"SuppressedErrors":{"diffs":null,"metrics":{"Left":{"Int":3}}}}}}},"tool":"DRD"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} + + + + + + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_one_helgrind_all_metrics.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_helgrind_all_metrics.txt new file mode 100644 index 000000000..c1e0edbb4 --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_helgrind_all_metrics.txt @@ -0,0 +1,19 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":"some_id","kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/helgrind.bench_play_game_100.log"],"out_paths":["/helgrind.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Left":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":12345,"part":null,"path":"/helgrind.bench_play_game_100.log","pid":23456,"thread":null}},"metrics_summary":{"ErrorTool":{"Contexts":{"diffs":null,"metrics":{"Left":{"Int":0}}},"Errors":{"diffs":null,"metrics":{"Left":{"Int":1}}},"SuppressedContexts":{"diffs":null,"metrics":{"Left":{"Int":2}}},"SuppressedErrors":{"diffs":null,"metrics":{"Left":{"Int":3}}}}}}],"total":{"regressions":[],"summary":{"ErrorTool":{"Contexts":{"diffs":null,"metrics":{"Left":{"Int":0}}},"Errors":{"diffs":null,"metrics":{"Left":{"Int":1}}},"SuppressedContexts":{"diffs":null,"metrics":{"Left":{"Int":2}}},"SuppressedErrors":{"diffs":null,"metrics":{"Left":{"Int":3}}}}}}},"tool":"Helgrind"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} + + + + + + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_one_memcheck_all_metrics.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_memcheck_all_metrics.txt new file mode 100644 index 000000000..075e8c3d7 --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_memcheck_all_metrics.txt @@ -0,0 +1,19 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":"some_id","kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/memcheck.bench_play_game_100.log"],"out_paths":["/memcheck.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Left":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":"HEAP SUMMARY:\n in use at exit: 544 bytes in 1 blocks\n total heap usage: 115 allocs, 114 frees, 3,255 bytes allocated\n\nLEAK SUMMARY:\n definitely lost: 0 bytes in 0 blocks\n indirectly lost: 0 bytes in 0 blocks\n possibly lost: 0 bytes in 0 blocks\n still reachable: 544 bytes in 1 blocks\n suppressed: 0 bytes in 0 blocks\nRerun with --leak-check=full to see details of leaked memory\n\nFor lists of detected and suppressed errors, rerun with: -s","parent_pid":12345,"part":null,"path":"/memcheck.bench_play_game_100.log","pid":23456,"thread":null}},"metrics_summary":{"ErrorTool":{"Contexts":{"diffs":null,"metrics":{"Left":{"Int":0}}},"Errors":{"diffs":null,"metrics":{"Left":{"Int":1}}},"SuppressedContexts":{"diffs":null,"metrics":{"Left":{"Int":2}}},"SuppressedErrors":{"diffs":null,"metrics":{"Left":{"Int":3}}}}}}],"total":{"regressions":[],"summary":{"ErrorTool":{"Contexts":{"diffs":null,"metrics":{"Left":{"Int":0}}},"Errors":{"diffs":null,"metrics":{"Left":{"Int":1}}},"SuppressedContexts":{"diffs":null,"metrics":{"Left":{"Int":2}}},"SuppressedErrors":{"diffs":null,"metrics":{"Left":{"Int":3}}}}}}},"tool":"Memcheck"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} + + + + + + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_one_tool_without_metrics.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_tool_without_metrics.txt new file mode 100644 index 000000000..8126815a9 --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_one_tool_without_metrics.txt @@ -0,0 +1,17 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":"some_id","kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/massif.bench_play_game_100.log"],"out_paths":["/massif.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Left":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":12345,"part":null,"path":"/massif.bench_play_game_100.log","pid":23456,"thread":null}},"metrics_summary":"None"}],"total":{"regressions":[],"summary":"None"}},"tool":"Massif"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} + + + + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... From 0657e75bd8f0943cee943e72bb5aca1ccc767d40 Mon Sep 17 00:00:00 2001 From: gamma0987 Date: Sat, 8 Aug 2026 20:40:57 +0200 Subject: [PATCH 05/11] Bump gungraun version in example --- examples/rust/gungraun/Cargo.lock | 117 ++++++++++++++++++++++++------ examples/rust/gungraun/Cargo.toml | 2 +- 2 files changed, 96 insertions(+), 23 deletions(-) diff --git a/examples/rust/gungraun/Cargo.lock b/examples/rust/gungraun/Cargo.lock index 94fbe7d6d..ccf6570e9 100644 --- a/examples/rust/gungraun/Cargo.lock +++ b/examples/rust/gungraun/Cargo.lock @@ -3,12 +3,15 @@ version = 4 [[package]] -name = "bincode" -version = "1.3.3" +name = "bincode-next" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +checksum = "1d6626829353ae29293be5c86f42de5f0468bc758af074b0c7d08f07e538ccbc" dependencies = [ + "pastey", + "rapidhash", "serde", + "unty-next", ] [[package]] @@ -29,9 +32,25 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn", + "syn 2.0.114", ] +[[package]] +name = "either-or-both" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717164c227120ba9ddf3e2b32305fc0122741d3ee41a54968eae7573ee01933" +dependencies = [ + "indexmap", + "serde", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "game" version = "0.1.0" @@ -41,11 +60,11 @@ dependencies = [ [[package]] name = "gungraun" -version = "0.18.0" +version = "0.19.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7548ffb27cd5b2a15832eda0045a3f3298c83c3c04ff9eec647d61822e7effa" +checksum = "9300d38d30facf6870c15bc9e243edcc47e5ddc270c9d2c1ae824a00b1faea79" dependencies = [ - "bincode", + "bincode-next", "derive_more", "gungraun-macros", "gungraun-runner", @@ -53,29 +72,46 @@ dependencies = [ [[package]] name = "gungraun-macros" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35c7fb6133421db1cf752b7a2838d9277a26810ccaeeca7aa449f96ad7c2b01" +checksum = "d7f3214bae6cfd6739f4f29edb262bae439c6393a7b7b12c4eeb96417c2e50df" dependencies = [ "derive_more", - "proc-macro-error2", + "proc-macro-error3", "proc-macro2", "quote", "rustc_version", "serde", "serde_json", - "syn", + "syn 2.0.114", ] [[package]] name = "gungraun-runner" -version = "0.18.0" +version = "0.19.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "365ec7a45b5dd0b147b2efd3e3f9517274ce567c6226c8e84c0a3350f66d4375" +checksum = "47c68c92812da579a2510a2cc702d5aa3251992b9662d4a98502ca46e0cbe16e" dependencies = [ + "either-or-both", "serde", ] +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "itoa" version = "1.0.17" @@ -89,25 +125,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" +name = "pastey" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" + +[[package]] +name = "proc-macro-error-attr3" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +checksum = "b0084e6206a967a2dad822180626b2f6b07a3b379325e8f1ec0438e33a469ba7" dependencies = [ "proc-macro2", "quote", ] [[package]] -name = "proc-macro-error2" -version = "2.0.1" +name = "proc-macro-error3" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +checksum = "0cf066225f2373bc711684792b69bdeac0356019b007e721090c24d92d5d5a50" dependencies = [ - "proc-macro-error-attr2", + "proc-macro-error-attr3", "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -128,6 +170,15 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rapidhash" +version = "4.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5da7e78a036ce858e8d55b7e7dc8ba3a88b78350fd2155d3591bbd966b58589e" +dependencies = [ + "rustversion", +] + [[package]] name = "rustc_version" version = "0.4.1" @@ -137,6 +188,12 @@ dependencies = [ "semver", ] +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + [[package]] name = "semver" version = "1.0.27" @@ -170,7 +227,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.114", ] [[package]] @@ -197,12 +254,28 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +dependencies = [ + "proc-macro2", + "unicode-ident", +] + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unty-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16062d030850f35054e37746427b9febb74a2f24c9c6dd6fa2d0c13c5f53221e" + [[package]] name = "zmij" version = "1.0.20" diff --git a/examples/rust/gungraun/Cargo.toml b/examples/rust/gungraun/Cargo.toml index bfb6407d2..6582b72cc 100644 --- a/examples/rust/gungraun/Cargo.toml +++ b/examples/rust/gungraun/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dev-dependencies] -gungraun = "0.18.0" +gungraun = "0.19.4" [[bench]] name = "play_game" From 02e4a21d0bb9ca29880bfc423fa1111913398699 Mon Sep 17 00:00:00 2001 From: gamma0987 Date: Sun, 9 Aug 2026 01:51:55 +0200 Subject: [PATCH 06/11] Regenerate types for rust_gungraun_json adapter --- services/api/openapi.json | 1 + services/console/src/types/bencher.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/services/api/openapi.json b/services/api/openapi.json index 984250e3b..9c68bbd45 100644 --- a/services/api/openapi.json +++ b/services/api/openapi.json @@ -11845,6 +11845,7 @@ "rust_criterion", "rust_iai", "rust_gungraun", + "rust_gungraun_json", "cpp", "cpp_google", "cpp_catch2", diff --git a/services/console/src/types/bencher.ts b/services/console/src/types/bencher.ts index 1a9b207a7..d638da2fd 100644 --- a/services/console/src/types/bencher.ts +++ b/services/console/src/types/bencher.ts @@ -1047,6 +1047,7 @@ export enum Adapter { RustCriterion = "rust_criterion", RustIai = "rust_iai", RustGungraun = "rust_gungraun", + RustGungraunJson = "rust_gungraun_json", Cpp = "cpp", CppGoogle = "cpp_google", CppCatch2 = "cpp_catch2", From b4544de0b56a5f73f9fba127c29449fcd015f7f8 Mon Sep 17 00:00:00 2001 From: gamma0987 Date: Mon, 10 Aug 2026 19:25:20 +0200 Subject: [PATCH 07/11] fix missing from_sql for RUST_GU8NGRAUN_JSON_INT --- lib/bencher_json/src/project/report.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/bencher_json/src/project/report.rs b/lib/bencher_json/src/project/report.rs index 1a256f7d2..9d74e2c92 100644 --- a/lib/bencher_json/src/project/report.rs +++ b/lib/bencher_json/src/project/report.rs @@ -311,6 +311,7 @@ mod adapter { RUST_CRITERION_INT => Ok(Self::RustCriterion), RUST_IAI_INT => Ok(Self::RustIai), RUST_GUNGRAUN_INT => Ok(Self::RustGungraun), + RUST_GUNGRAUN_JSON_INT => Ok(Self::RustGungraunJson), CPP_INT => Ok(Self::Cpp), CPP_GOOGLE_INT => Ok(Self::CppGoogle), CPP_CATCH2_INT => Ok(Self::CppCatch2), From 1f105e3f3dcff97574705e625f271db609f6566e Mon Sep 17 00:00:00 2001 From: gamma0987 Date: Tue, 11 Aug 2026 00:36:27 +0200 Subject: [PATCH 08/11] rust_gungraun adapter delegate to rust_gungraun_json, rust_gungraun_stdout --- lib/bencher_adapter/src/adapters/magic.rs | 18 +- .../src/adapters/rust/gungraun.rs | 1209 +--------------- .../src/adapters/rust/gungraun_stdout.rs | 1216 +++++++++++++++++ lib/bencher_adapter/src/adapters/rust/mod.rs | 43 +- lib/bencher_adapter/src/lib.rs | 6 +- lib/bencher_json/src/project/report.rs | 10 +- services/api/openapi.json | 1 + services/console/src/types/bencher.ts | 1 + 8 files changed, 1287 insertions(+), 1217 deletions(-) create mode 100644 lib/bencher_adapter/src/adapters/rust/gungraun_stdout.rs diff --git a/lib/bencher_adapter/src/adapters/magic.rs b/lib/bencher_adapter/src/adapters/magic.rs index 591364f5d..b8f1821b7 100644 --- a/lib/bencher_adapter/src/adapters/magic.rs +++ b/lib/bencher_adapter/src/adapters/magic.rs @@ -36,7 +36,8 @@ mod test_magic { python::{asv::test_python_asv, pytest::test_python_pytest}, ruby::benchmark::test_ruby_benchmark, rust::{ - bench::test_rust_bench, criterion::test_rust_criterion, gungraun::test_rust_gungraun, + bench::test_rust_bench, criterion::test_rust_criterion, + gungraun_json::test_rust_gungraun_json, gungraun_stdout::test_rust_gungraun_stdout, iai::test_rust_iai, }, shell::hyperfine::test_shell_hyperfine, @@ -147,17 +148,26 @@ mod test_magic { } #[test] - fn adapter_magic_rust_gungraun() { + fn adapter_magic_rust_gungraun_stdout() { let results = convert_file_path::( "./tool_output/rust/gungraun/without-optional-metrics.txt", ); - test_rust_gungraun::validate_adapter_rust_gungraun( + test_rust_gungraun_stdout::validate_adapter_rust_gungraun_stdout( &results, - &test_rust_gungraun::OptionalMetrics::default(), + &test_rust_gungraun_stdout::OptionalMetrics::default(), ); } + #[test] + fn adapter_magic_rust_gungraun_json() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_callgrind_diff.txt", + ); + + test_rust_gungraun_json::validate_adapter_rust_gungraun_json(&results); + } + #[test] fn adapter_magic_shell_hyperfine() { let results = convert_file_path::("./tool_output/shell/hyperfine/two.json"); diff --git a/lib/bencher_adapter/src/adapters/rust/gungraun.rs b/lib/bencher_adapter/src/adapters/rust/gungraun.rs index adc83e84a..8701c64b5 100644 --- a/lib/bencher_adapter/src/adapters/rust/gungraun.rs +++ b/lib/bencher_adapter/src/adapters/rust/gungraun.rs @@ -1,1211 +1,46 @@ -use std::ops::Neg as _; +use crate::Adaptable; -use bencher_json::{ - BenchmarkName, JsonNewMetric, - project::{ - measure::built_in::{BuiltInMeasure as _, gungraun}, - report::JsonAverage, - }, -}; -use nom::{ - IResult, Parser, - branch::alt, - bytes::complete::{is_a, is_not, tag, take_until1}, - character::complete::{char, space0, space1}, - combinator::{map, opt, peek, recognize}, - error::Error, - multi::{many0, many1}, - sequence::{delimited, preceded, terminated}, -}; - -use crate::{ - Adaptable, Settings, - adapters::util::parse_f64, - results::adapter_results::{AdapterResults, GungraunMeasure}, -}; +use super::{gungraun_json::AdapterRustGungraunJson, gungraun_stdout::AdapterRustGungraunStdout}; pub struct AdapterRustGungraun; impl Adaptable for AdapterRustGungraun { - fn parse(input: &str, settings: Settings) -> Option { - match settings.average { - None => {}, - Some(JsonAverage::Mean | JsonAverage::Median) => { - return None; // 'gungraun' results are for a single run only. - }, - } - - // Clean up the input by removing ANSI escape codes: - let input = strip_ansi_escapes::strip_str(input); - - let benchmarks = match multiple_benchmarks().parse(&*input) { - Err(error) => { - debug_assert!(false, "Error parsing input:\n{error:#?}"); - return None; - }, - Ok((remainder, benchmarks)) => { - debug_assert_eq!(remainder.len(), 0, "Unparsed trailing input:\n{remainder}"); - benchmarks - }, - }; - - AdapterResults::new_gungraun(benchmarks) + fn parse(input: &str, settings: crate::Settings) -> Option { + AdapterRustGungraunJson::parse(input, settings) + .or_else(|| AdapterRustGungraunStdout::parse(input, settings)) } } -fn multiple_benchmarks<'a>() --> impl Parser<&'a str, Output = Vec<(BenchmarkName, Vec)>, Error = Error<&'a str>> -{ - map( - many0(alt(( - // Try to parse a single benchmark: - single_benchmark(), - // Otherwise, parse/ignore unrelated lines: - map(terminated(not_line_ending(), opt(line_ending())), |_| None), - // Otherwise, parse/ignore empty lines: - map(line_ending(), |_| None), - ))), - // Skip 'None' resulting from empty/unrelated lines: - |benchmarks| benchmarks.into_iter().flatten().collect(), - ) -} - -fn single_benchmark<'a>() --> impl Parser<&'a str, Output = Option<(BenchmarkName, Vec)>, Error = Error<&'a str>> -{ - map( - ( - terminated( - recognize(( - is_not(":\r\n \t"), - tag("::"), - is_not(":\r\n \t"), - tag("::"), - not_benchmark_name_end(), - )), - benchmark_name_end(), - ), - many0(alt(( - // Callgrind tool if it was enabled: - callgrind_tool_measures(), - // Cachegrind tool if it was enabled: - cachegrind_tool_measures(), - // Add DHAT tool measures if it was enabled: - dhat_tool_measures(), - // Add Memcheck tool measures if it was enabled: - memcheck_tool_measures(), - // Add Helgrind tool measures if it was enabled: - helgrind_tool_measures(), - // Add Drd tool measures if it was enabled: - drd_tool_measures(), - ))), - ), - |(benchmark_name, measures)| { - // trim here to avoid loose `\r` chars at the end of the string because of the - // `not_benchmark_name_end` parser. It's maybe not a bad idea anyways. - let benchmark_name = benchmark_name.trim().parse().ok()?; - let measures = measures.into_iter().flatten().collect(); - - Some((benchmark_name, measures)) - }, - ) -} - -fn callgrind_tool_measures<'a>() --> impl Parser<&'a str, Output = Vec, Error = Error<&'a str>> { - map( - preceded(opt(tool_name_line("CALLGRIND")), many1(metric_line())), - |metrics| { - metrics - .into_iter() - .map(|(metric_name, json)| match metric_name.as_str() { - gungraun::Instructions::NAME_STR => GungraunMeasure::Instructions(json), - gungraun::L1Hits::NAME_STR => GungraunMeasure::L1Hits(json), - gungraun::L2Hits::NAME_STR => GungraunMeasure::L2Hits(json), - gungraun::LLHits::NAME_STR => GungraunMeasure::LLHits(json), - gungraun::RamHits::NAME_STR => GungraunMeasure::RamHits(json), - gungraun::TotalReadWrite::NAME_STR => GungraunMeasure::TotalReadWrite(json), - gungraun::EstimatedCycles::NAME_STR => GungraunMeasure::EstimatedCycles(json), - gungraun::Dr::NAME_STR => GungraunMeasure::DataCacheReads(json), - gungraun::Dw::NAME_STR => GungraunMeasure::DataCacheWrites(json), - gungraun::I1mr::NAME_STR => GungraunMeasure::L1InstrCacheReadMisses(json), - gungraun::D1mr::NAME_STR => GungraunMeasure::L1DataCacheReadMisses(json), - gungraun::D1mw::NAME_STR => GungraunMeasure::L1DataCacheWriteMisses(json), - gungraun::ILmr::NAME_STR => GungraunMeasure::LLInstrCacheReadMisses(json), - gungraun::DLmr::NAME_STR => GungraunMeasure::LLDataCacheReadMisses(json), - gungraun::DLmw::NAME_STR => GungraunMeasure::LLDataCacheWriteMisses(json), - gungraun::I1MissRate::NAME_STR => GungraunMeasure::L1InstrCacheMissRate(json), - gungraun::LLiMissRate::NAME_STR => GungraunMeasure::LLInstrCacheMissRate(json), - gungraun::D1MissRate::NAME_STR => GungraunMeasure::L1DataCacheMissRate(json), - gungraun::LLdMissRate::NAME_STR => GungraunMeasure::LLDataCacheMissRate(json), - gungraun::LLMissRate::NAME_STR => GungraunMeasure::LLCacheMissRate(json), - gungraun::L1HitRate::NAME_STR => GungraunMeasure::L1HitRate(json), - gungraun::LLHitRate::NAME_STR => GungraunMeasure::LLHitRate(json), - gungraun::RamHitRate::NAME_STR => GungraunMeasure::RamHitRate(json), - gungraun::SysCount::NAME_STR => GungraunMeasure::NumberSystemCalls(json), - gungraun::SysTime::NAME_STR => GungraunMeasure::TimeSystemCalls(json), - gungraun::SysCpuTime::NAME_STR => GungraunMeasure::CpuTimeSystemCalls(json), - gungraun::GlobalBusEvents::NAME_STR => GungraunMeasure::GlobalBusEvents(json), - gungraun::Bc::NAME_STR => GungraunMeasure::ExecutedConditionalBranches(json), - gungraun::Bcm::NAME_STR => { - GungraunMeasure::MispredictedConditionalBranches(json) - }, - gungraun::Bi::NAME_STR => GungraunMeasure::ExecutedIndirectBranches(json), - gungraun::Bim::NAME_STR => GungraunMeasure::MispredictedIndirectBranches(json), - gungraun::ILdmr::NAME_STR => GungraunMeasure::DirtyMissInstructionRead(json), - gungraun::DLdmr::NAME_STR => GungraunMeasure::DirtyMissDataRead(json), - gungraun::DLdmw::NAME_STR => GungraunMeasure::DirtyMissDataWrite(json), - gungraun::AcCost1::NAME_STR => GungraunMeasure::L1BadTemporalLocality(json), - gungraun::AcCost2::NAME_STR => GungraunMeasure::LLBadTemporalLocality(json), - gungraun::SpLoss1::NAME_STR => GungraunMeasure::L1BadSpatialLocality(json), - gungraun::SpLoss2::NAME_STR => GungraunMeasure::LLBadSpatialLocality(json), - _ => GungraunMeasure::Unknown, - }) - .collect() - }, - ) -} - -fn cachegrind_tool_measures<'a>() --> impl Parser<&'a str, Output = Vec, Error = Error<&'a str>> { - map( - preceded(tool_name_line("CACHEGRIND"), many1(metric_line())), - |metrics| { - metrics - .into_iter() - .map(|(metric_name, json)| match metric_name.as_str() { - gungraun::Instructions::NAME_STR => GungraunMeasure::Instructions(json), - gungraun::L1Hits::NAME_STR => GungraunMeasure::L1Hits(json), - gungraun::L2Hits::NAME_STR => GungraunMeasure::L2Hits(json), - gungraun::LLHits::NAME_STR => GungraunMeasure::LLHits(json), - gungraun::RamHits::NAME_STR => GungraunMeasure::RamHits(json), - gungraun::TotalReadWrite::NAME_STR => GungraunMeasure::TotalReadWrite(json), - gungraun::EstimatedCycles::NAME_STR => GungraunMeasure::EstimatedCycles(json), - gungraun::Dr::NAME_STR => GungraunMeasure::DataCacheReads(json), - gungraun::Dw::NAME_STR => GungraunMeasure::DataCacheWrites(json), - gungraun::I1mr::NAME_STR => GungraunMeasure::L1InstrCacheReadMisses(json), - gungraun::D1mr::NAME_STR => GungraunMeasure::L1DataCacheReadMisses(json), - gungraun::D1mw::NAME_STR => GungraunMeasure::L1DataCacheWriteMisses(json), - gungraun::ILmr::NAME_STR => GungraunMeasure::LLInstrCacheReadMisses(json), - gungraun::DLmr::NAME_STR => GungraunMeasure::LLDataCacheReadMisses(json), - gungraun::DLmw::NAME_STR => GungraunMeasure::LLDataCacheWriteMisses(json), - gungraun::I1MissRate::NAME_STR => GungraunMeasure::L1InstrCacheMissRate(json), - gungraun::LLiMissRate::NAME_STR => GungraunMeasure::LLInstrCacheMissRate(json), - gungraun::D1MissRate::NAME_STR => GungraunMeasure::L1DataCacheMissRate(json), - gungraun::LLdMissRate::NAME_STR => GungraunMeasure::LLDataCacheMissRate(json), - gungraun::LLMissRate::NAME_STR => GungraunMeasure::LLCacheMissRate(json), - gungraun::L1HitRate::NAME_STR => GungraunMeasure::L1HitRate(json), - gungraun::LLHitRate::NAME_STR => GungraunMeasure::LLHitRate(json), - gungraun::RamHitRate::NAME_STR => GungraunMeasure::RamHitRate(json), - _ => GungraunMeasure::Unknown, - }) - .collect() - }, - ) -} - -fn dhat_tool_measures<'a>() --> impl Parser<&'a str, Output = Vec, Error = Error<&'a str>> { - map( - preceded(tool_name_line("DHAT"), many1(metric_line())), - |metrics| { - metrics - .into_iter() - .map(|(metric_name, json)| match metric_name.as_str() { - gungraun::TotalBytes::NAME_STR => GungraunMeasure::TotalBytes(json), - gungraun::TotalBlocks::NAME_STR => GungraunMeasure::TotalBlocks(json), - gungraun::TotalUnits::NAME_STR => GungraunMeasure::TotalUnits(json), - gungraun::TotalEvents::NAME_STR => GungraunMeasure::TotalEvents(json), - gungraun::TotalLifetimes::NAME_STR => GungraunMeasure::TotalLifetimes(json), - gungraun::AtTGmaxBytes::NAME_STR => GungraunMeasure::AtTGmaxBytes(json), - gungraun::AtTGmaxBlocks::NAME_STR => GungraunMeasure::AtTGmaxBlocks(json), - gungraun::AtTEndBytes::NAME_STR => GungraunMeasure::AtTEndBytes(json), - gungraun::AtTEndBlocks::NAME_STR => GungraunMeasure::AtTEndBlocks(json), - gungraun::ReadsBytes::NAME_STR => GungraunMeasure::ReadsBytes(json), - gungraun::WritesBytes::NAME_STR => GungraunMeasure::WritesBytes(json), - gungraun::MaximumBytes::NAME_STR => GungraunMeasure::MaximumBytes(json), - gungraun::MaximumBlocks::NAME_STR => GungraunMeasure::MaximumBlocks(json), - _ => GungraunMeasure::Unknown, - }) - .collect() - }, - ) -} - -fn memcheck_tool_measures<'a>() --> impl Parser<&'a str, Output = Vec, Error = Error<&'a str>> { - map( - preceded(tool_name_line("MEMCHECK"), many1(metric_line())), - |metrics| { - metrics - .into_iter() - .map(|(metric_name, json)| match metric_name.as_str() { - gungraun::MemcheckErrors::NAME_STR => GungraunMeasure::MemcheckErrors(json), - gungraun::MemcheckContexts::NAME_STR => GungraunMeasure::MemcheckContexts(json), - gungraun::MemcheckSuppressedErrors::NAME_STR => { - GungraunMeasure::MemcheckSuppressedErrors(json) - }, - gungraun::MemcheckSuppressedContexts::NAME_STR => { - GungraunMeasure::MemcheckSuppressedContexts(json) - }, - _ => GungraunMeasure::Unknown, - }) - .collect() - }, - ) -} - -fn helgrind_tool_measures<'a>() --> impl Parser<&'a str, Output = Vec, Error = Error<&'a str>> { - map( - preceded(tool_name_line("HELGRIND"), many1(metric_line())), - |metrics| { - metrics - .into_iter() - .map(|(metric_name, json)| match metric_name.as_str() { - gungraun::HelgrindErrors::NAME_STR => GungraunMeasure::HelgrindErrors(json), - gungraun::HelgrindContexts::NAME_STR => GungraunMeasure::HelgrindContexts(json), - gungraun::HelgrindSuppressedErrors::NAME_STR => { - GungraunMeasure::HelgrindSuppressedErrors(json) - }, - gungraun::HelgrindSuppressedContexts::NAME_STR => { - GungraunMeasure::HelgrindSuppressedContexts(json) - }, - _ => GungraunMeasure::Unknown, - }) - .collect() - }, - ) -} - -fn drd_tool_measures<'a>() --> impl Parser<&'a str, Output = Vec, Error = Error<&'a str>> { - map( - preceded(tool_name_line("DRD"), many1(metric_line())), - |metrics| { - metrics - .into_iter() - .map(|(metric_name, json)| match metric_name.as_str() { - gungraun::DrdErrors::NAME_STR => GungraunMeasure::DrdErrors(json), - gungraun::DrdContexts::NAME_STR => GungraunMeasure::DrdContexts(json), - gungraun::DrdSuppressedErrors::NAME_STR => { - GungraunMeasure::DrdSuppressedErrors(json) - }, - gungraun::DrdSuppressedContexts::NAME_STR => { - GungraunMeasure::DrdSuppressedContexts(json) - }, - _ => GungraunMeasure::Unknown, - }) - .collect() - }, - ) -} - -fn tool_name_line<'a>( - tool_name: &'static str, -) -> impl Parser<&'a str, Output = &'a str, Error = Error<&'a str>> { - delimited( - (space1, many1(tag("=")), tag(" ")), - tag(tool_name), - (tag(" "), many1(tag("=")), line_ending()), - ) -} - -fn metric_line<'a>() --> impl Parser<&'a str, Output = (String, JsonNewMetric), Error = Error<&'a str>> { - map( - ( - space1, - is_not(":\r\n"), - char(':'), - space1, - // the current run value: - parse_f64, - char('|'), - alt(( - // No previous run: - recognize(( - tag("N/A"), - space1, - delimited(char('('), many1(char('*')), char(')')), - )), - // Comparison to previous run: - recognize(( - parse_f64, - space0, - alt(( - recognize(delimited(char('('), tag("No change"), char(')'))), - recognize(( - delimited(char('('), alt((infinity, percent)), char(')')), - space1, - delimited(char('['), alt((infinity, factor)), char(']')), - )), - )), - )), - )), - line_ending(), - ), - |(_, metric_name, _, _, current_value, _, _, _)| { - ( - metric_name.to_owned(), - JsonNewMetric { - value: current_value.into(), - lower_value: None, - upper_value: None, - }, - ) - }, - ) -} - -fn infinity(input: &str) -> IResult<&str, f64> { - map( - ( - alt((many1(char('+')), many1(char('-')))), - tag("inf"), - alt((many1(char('+')), many1(char('-')))), - ), - |(signs, _, _)| { - // The indexing is safe due to the usage of `many1` above - #[expect(clippy::indexing_slicing, reason = "many1 guarantees non-empty vec")] - let sign = signs[0]; - if sign == '+' { - f64::INFINITY - } else { - f64::NEG_INFINITY - } - }, - ) - .parse(input) -} - -fn factor(input: &str) -> IResult<&str, f64> { - map( - (alt((char('+'), char('-'))), parse_f64, char('x')), - |(sign, num, _)| { - if sign == '+' { num } else { num.neg() } - }, - ) - .parse(input) -} - -fn percent(input: &str) -> IResult<&str, f64> { - map( - (alt((char('+'), char('-'))), parse_f64, char('%')), - |(sign, num, _)| { - if sign == '+' { num } else { num.neg() } - }, - ) - .parse(input) -} - -fn line_ending<'a>() -> impl Parser<&'a str, Output = &'a str, Error = Error<&'a str>> { - is_a("\r\n") -} - -fn not_line_ending<'a>() -> impl Parser<&'a str, Output = &'a str, Error = Error<&'a str>> { - // Note: `not(line_ending)` doesn't work here, as it won't consume the matched characters - is_not("\r\n") -} - -/// Parser that matches the benchmark name ending sequence, excluding the two spaces -fn benchmark_name_end<'a>() --> impl Parser<&'a str, Output = (&'a str, &'a str), Error = Error<&'a str>> { - // we only peek here so the `metric_line` parser can match the first spaces too - (line_ending(), peek(tag(" "))) -} - -/// A parser that matches input until it encounters the benchmark name end sequence. -/// -/// Similar to the `benchmark_name_end` parser, this parser addresses an unusual behavior in -/// `gungraun` (iai-callgrind) by allowing benchmark names to span multiple lines. While this -/// behavior is not a bug in `gungraun`, it deviates from the original intent. If there are multiple -/// lines they don't start with two spaces, so we can use that as test for the end of the benchmark -/// name. -fn not_benchmark_name_end<'a>() -> impl Parser<&'a str, Output = &'a str, Error = Error<&'a str>> { - // Ignore the `\r\n` possibility here and instead trim the benchmark name later - take_until1("\n ") -} - #[cfg(test)] pub(crate) mod test_rust_gungraun { - use crate::{AdapterResults, adapters::test_util::convert_file_path}; - use bencher_json::project::measure::built_in::{BuiltInMeasure as _, gungraun}; - use ordered_float::OrderedFloat; - use pretty_assertions::assert_eq; - - use super::AdapterRustGungraun; - use std::collections::HashMap; - - #[test] - fn without_optional_metrics() { - let results = convert_file_path::( - "./tool_output/rust/gungraun/without-optional-metrics.txt", - ); - - validate_adapter_rust_gungraun(&results, &OptionalMetrics::default()); - } - - #[test] - fn with_dhat() { - let results = - convert_file_path::("./tool_output/rust/gungraun/with-dhat.txt"); - - validate_adapter_rust_gungraun( - &results, - &OptionalMetrics { - dhat: true, - ..Default::default() - }, - ); - } - - #[test] - fn with_dhat_first_then_callgrind() { - let results = convert_file_path::( - "./tool_output/rust/gungraun/dhat-then-callgrind.txt", - ); - - validate_adapter_rust_gungraun( - &results, - &OptionalMetrics { - dhat: true, - ..Default::default() - }, - ); - } - - #[test] - fn with_dhat_and_global_bus_events() { - let results = convert_file_path::( - "./tool_output/rust/gungraun/with-dhat-and-global-bus-events.txt", - ); - - validate_adapter_rust_gungraun( - &results, - &OptionalMetrics { - dhat: true, - global_bus_events: true, - }, - ); - } - - #[test] - fn delta() { - let results = - convert_file_path::("./tool_output/rust/gungraun/delta.txt"); - - validate_adapter_rust_gungraun(&results, &OptionalMetrics::default()); - } - - #[test] - fn delta_with_infinity() { - let results = convert_file_path::( - "./tool_output/rust/gungraun/delta_with_inf.txt", - ); - - assert_eq!(results.inner.len(), 2); - - { - let expected = HashMap::from([ - (gungraun::Instructions::SLUG_STR, 1_734.0), - (gungraun::L1Hits::SLUG_STR, 2_359.0), - (gungraun::L2Hits::SLUG_STR, 0.0), - (gungraun::RamHits::SLUG_STR, 3.0), - (gungraun::TotalReadWrite::SLUG_STR, 0.0), - (gungraun::EstimatedCycles::SLUG_STR, 2_464.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::bench_fibonacci_group::bench_fibonacci short:10", - ); - } - - { - let expected = HashMap::from([ - (gungraun::Instructions::SLUG_STR, 26_214_734.0), - (gungraun::L1Hits::SLUG_STR, 35_638_619.0), - (gungraun::L2Hits::SLUG_STR, 0.0), - (gungraun::RamHits::SLUG_STR, 3.0), - (gungraun::TotalReadWrite::SLUG_STR, 35_638_622.0), - (gungraun::EstimatedCycles::SLUG_STR, 35_638_724.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::bench_fibonacci_group::bench_fibonacci long:30", - ); - } - } - - #[test] - fn with_summary_and_regressions() { - let results = convert_file_path::( - "./tool_output/rust/gungraun/with-summary-and-regressions.txt", - ); - - validate_adapter_rust_gungraun(&results, &OptionalMetrics::default()); - } - - #[test] - fn with_gungraun_summary() { - let results = convert_file_path::( - "./tool_output/rust/gungraun/with-gungraun-summary.txt", - ); - - validate_adapter_rust_gungraun(&results, &OptionalMetrics::default()); - } - - #[test] - fn ansi_escapes_issue_345() { - let results = convert_file_path::( - "./tool_output/rust/gungraun/ansi-escapes.txt", - ); - - validate_adapter_rust_gungraun(&results, &OptionalMetrics::default()); - } - - #[test] - fn with_ge() { - let results = - convert_file_path::("./tool_output/rust/gungraun/with-ge.txt"); + use crate::adapters::{ + rust::{ + gungraun_json::test_rust_gungraun_json::validate_adapter_rust_gungraun_json, + gungraun_stdout::{AdapterRustGungraunStdout, test_rust_gungraun_stdout}, + }, + test_util::convert_file_path, + }; - validate_adapter_rust_gungraun( - &results, - &OptionalMetrics { - global_bus_events: true, - ..Default::default() - }, - ); - } + use super::AdapterRustGungraunJson; #[test] - fn without_cachesim() { - use gungraun::*; - - let results = convert_file_path::( - "./tool_output/rust/gungraun/without-cachesim.txt", + fn json() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_callgrind_diff.txt", ); - assert_eq!(results.inner.len(), 2); - - { - let expected = HashMap::from([(Instructions::SLUG_STR, 1734.0)]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::bench_fibonacci_group::bench_fibonacci short:10", - ); - } - - { - let expected = HashMap::from([(Instructions::SLUG_STR, 26_214_734.0)]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::bench_fibonacci_group::bench_fibonacci long:30", - ); - } + validate_adapter_rust_gungraun_json(&results); } #[test] - fn callgrind_mixed_order() { - use gungraun::*; - - let results = convert_file_path::( - "./tool_output/rust/gungraun/callgrind-mixed-order.txt", - ); - - assert_eq!(results.inner.len(), 2); - - let expected = HashMap::from([ - (Instructions::SLUG_STR, 1.0), - (Dr::SLUG_STR, 2.0), - (Dw::SLUG_STR, 3.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::callgrind_format mixed_1", + fn stdout() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/without-optional-metrics.txt", ); - compare_benchmark( - &expected, + test_rust_gungraun_stdout::validate_adapter_rust_gungraun_stdout( &results, - "rust_iai_callgrind::custom_format::callgrind_format mixed_2", + &test_rust_gungraun_stdout::OptionalMetrics::default(), ); } - - #[test] - fn callgrind_ll_hits() { - use gungraun::*; - - let results = convert_file_path::( - "./tool_output/rust/gungraun/callgrind-ll-hits.txt", - ); - - assert_eq!(results.inner.len(), 2); - - { - let expected = - HashMap::from([(Instructions::SLUG_STR, 10.0), (LLHits::SLUG_STR, 20.0)]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::callgrind_format ll_hits", - ); - } - - { - let expected = HashMap::from([(Instructions::SLUG_STR, 1.0), (LLHits::SLUG_STR, 2.0)]); - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::callgrind_format ll_hits_mixed", - ); - } - } - - #[test] - fn callgrind_all() { - use gungraun::*; - - let results = convert_file_path::( - "./tool_output/rust/gungraun/callgrind-all.txt", - ); - - assert_eq!(results.inner.len(), 2); - - { - let expected = HashMap::from([ - (Instructions::SLUG_STR, 1.0), - (Dr::SLUG_STR, 2.0), - (Dw::SLUG_STR, 3.0), - (I1mr::SLUG_STR, 4.0), - (D1mr::SLUG_STR, 5.0), - (D1mw::SLUG_STR, 6.0), - (ILmr::SLUG_STR, 7.0), - (DLmr::SLUG_STR, 8.0), - (DLmw::SLUG_STR, 9.0), - (I1MissRate::SLUG_STR, 10.0), - (LLiMissRate::SLUG_STR, 11.0), - (D1MissRate::SLUG_STR, 12.0), - (LLdMissRate::SLUG_STR, 13.0), - (LLMissRate::SLUG_STR, 14.0), - (L1Hits::SLUG_STR, 15.0), - (L2Hits::SLUG_STR, 16.0), - (RamHits::SLUG_STR, 17.0), - (L1HitRate::SLUG_STR, 18.0), - (LLHitRate::SLUG_STR, 19.0), - (RamHitRate::SLUG_STR, 20.0), - (TotalReadWrite::SLUG_STR, 21.0), - (EstimatedCycles::SLUG_STR, 22.0), - (SysCount::SLUG_STR, 23.0), - (SysTime::SLUG_STR, 24.0), - (SysCpuTime::SLUG_STR, 25.0), - (GlobalBusEvents::SLUG_STR, 26.0), - (Bc::SLUG_STR, 27.0), - (Bcm::SLUG_STR, 28.0), - (Bi::SLUG_STR, 29.0), - (Bim::SLUG_STR, 30.0), - (ILdmr::SLUG_STR, 31.0), - (DLdmr::SLUG_STR, 32.0), - (DLdmw::SLUG_STR, 33.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::callgrind_format all_with_wb", - ); - } - - { - let expected = HashMap::from([ - (Instructions::SLUG_STR, 1.0), - (Dr::SLUG_STR, 2.0), - (Dw::SLUG_STR, 3.0), - (I1mr::SLUG_STR, 4.0), - (D1mr::SLUG_STR, 5.0), - (D1mw::SLUG_STR, 6.0), - (ILmr::SLUG_STR, 7.0), - (DLmr::SLUG_STR, 8.0), - (DLmw::SLUG_STR, 9.0), - (I1MissRate::SLUG_STR, 10.0), - (LLiMissRate::SLUG_STR, 11.0), - (D1MissRate::SLUG_STR, 12.0), - (LLdMissRate::SLUG_STR, 13.0), - (LLMissRate::SLUG_STR, 14.0), - (L1Hits::SLUG_STR, 15.0), - (L2Hits::SLUG_STR, 16.0), - (RamHits::SLUG_STR, 17.0), - (L1HitRate::SLUG_STR, 18.0), - (LLHitRate::SLUG_STR, 19.0), - (RamHitRate::SLUG_STR, 20.0), - (TotalReadWrite::SLUG_STR, 21.0), - (EstimatedCycles::SLUG_STR, 22.0), - (SysCount::SLUG_STR, 23.0), - (SysTime::SLUG_STR, 24.0), - (SysCpuTime::SLUG_STR, 25.0), - (GlobalBusEvents::SLUG_STR, 26.0), - (Bc::SLUG_STR, 27.0), - (Bcm::SLUG_STR, 28.0), - (Bi::SLUG_STR, 29.0), - (Bim::SLUG_STR, 30.0), - (AcCost1::SLUG_STR, 31.0), - (AcCost2::SLUG_STR, 32.0), - (SpLoss1::SLUG_STR, 33.0), - (SpLoss2::SLUG_STR, 34.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::callgrind_format all_with_cachuse", - ); - } - } - - #[test] - fn cachegrind() { - use gungraun::*; - - let results = - convert_file_path::("./tool_output/rust/gungraun/cachegrind.txt"); - - assert_eq!(results.inner.len(), 3); - - { - let expected = HashMap::from([(Instructions::SLUG_STR, 1.0)]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::cachegrind_format just_instructions", - ); - } - - { - let expected = HashMap::from([ - (I1MissRate::SLUG_STR, 1.0), - (Dr::SLUG_STR, 2.0), - (EstimatedCycles::SLUG_STR, 3.0), - (TotalReadWrite::SLUG_STR, 4.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::cachegrind_format metrics_mixed", - ); - } - - { - let expected = HashMap::from([ - (Instructions::SLUG_STR, 1.0), - (Dr::SLUG_STR, 2.0), - (Dw::SLUG_STR, 3.0), - (I1mr::SLUG_STR, 4.0), - (D1mr::SLUG_STR, 5.0), - (D1mw::SLUG_STR, 6.0), - (ILmr::SLUG_STR, 7.0), - (DLmr::SLUG_STR, 8.0), - (DLmw::SLUG_STR, 9.0), - (I1MissRate::SLUG_STR, 10.0), - (LLiMissRate::SLUG_STR, 11.0), - (D1MissRate::SLUG_STR, 12.0), - (LLdMissRate::SLUG_STR, 13.0), - (LLMissRate::SLUG_STR, 14.0), - (L1Hits::SLUG_STR, 15.0), - (L2Hits::SLUG_STR, 16.0), - (RamHits::SLUG_STR, 17.0), - (L1HitRate::SLUG_STR, 18.0), - (LLHitRate::SLUG_STR, 19.0), - (RamHitRate::SLUG_STR, 20.0), - (TotalReadWrite::SLUG_STR, 21.0), - (EstimatedCycles::SLUG_STR, 22.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::cachegrind_format all_metrics", - ); - } - } - - #[test] - fn memcheck() { - use gungraun::*; - - let results = - convert_file_path::("./tool_output/rust/gungraun/memcheck.txt"); - - assert_eq!(results.inner.len(), 3); - - { - let expected = HashMap::from([(MemcheckErrors::SLUG_STR, 1.0)]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::memcheck_format just_errors", - ); - } - - { - let expected = HashMap::from([ - (MemcheckContexts::SLUG_STR, 1.0), - (MemcheckSuppressedContexts::SLUG_STR, 2.0), - (MemcheckSuppressedErrors::SLUG_STR, 3.0), - (MemcheckErrors::SLUG_STR, 4.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::memcheck_format metrics_mixed", - ); - } - - { - let expected = HashMap::from([ - (MemcheckErrors::SLUG_STR, 1.0), - (MemcheckContexts::SLUG_STR, 2.0), - (MemcheckSuppressedErrors::SLUG_STR, 3.0), - (MemcheckSuppressedContexts::SLUG_STR, 4.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::memcheck_format all_metrics", - ); - } - } - - #[test] - fn helgrind() { - use gungraun::*; - - let results = - convert_file_path::("./tool_output/rust/gungraun/helgrind.txt"); - - assert_eq!(results.inner.len(), 3); - - { - let expected = HashMap::from([(HelgrindErrors::SLUG_STR, 1.0)]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::helgrind_format just_errors", - ); - } - - { - let expected = HashMap::from([ - (HelgrindContexts::SLUG_STR, 1.0), - (HelgrindSuppressedContexts::SLUG_STR, 2.0), - (HelgrindSuppressedErrors::SLUG_STR, 3.0), - (HelgrindErrors::SLUG_STR, 4.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::helgrind_format metrics_mixed", - ); - } - - { - let expected = HashMap::from([ - (HelgrindErrors::SLUG_STR, 1.0), - (HelgrindContexts::SLUG_STR, 2.0), - (HelgrindSuppressedErrors::SLUG_STR, 3.0), - (HelgrindSuppressedContexts::SLUG_STR, 4.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::helgrind_format all_metrics", - ); - } - } - - #[test] - fn drd() { - use gungraun::*; - - let results = - convert_file_path::("./tool_output/rust/gungraun/drd.txt"); - - assert_eq!(results.inner.len(), 3); - - { - let expected = HashMap::from([(DrdErrors::SLUG_STR, 1.0)]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::drd_format just_errors", - ); - } - - { - let expected = HashMap::from([ - (DrdContexts::SLUG_STR, 1.0), - (DrdSuppressedContexts::SLUG_STR, 2.0), - (DrdSuppressedErrors::SLUG_STR, 3.0), - (DrdErrors::SLUG_STR, 4.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::drd_format metrics_mixed", - ); - } - - { - let expected = HashMap::from([ - (DrdErrors::SLUG_STR, 1.0), - (DrdContexts::SLUG_STR, 2.0), - (DrdSuppressedErrors::SLUG_STR, 3.0), - (DrdSuppressedContexts::SLUG_STR, 4.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::custom_format::drd_format all_metrics", - ); - } - } - - #[test] - fn name_multiple_lines() { - use gungraun::*; - - let results = convert_file_path::( - "./tool_output/rust/gungraun/name_on_multiple_lines.txt", - ); - - assert_eq!(results.inner.len(), 2); - - { - let mut expected = HashMap::new(); - - expected.extend([ - (Instructions::SLUG_STR, 1.0), - (L1Hits::SLUG_STR, 2.0), - (L2Hits::SLUG_STR, 3.0), - (RamHits::SLUG_STR, 4.0), - (TotalReadWrite::SLUG_STR, 5.0), - (EstimatedCycles::SLUG_STR, 6.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::bench::multiple_lines id:string with two\nlines", - ); - } - - { - let mut expected = HashMap::new(); - - expected.extend([ - (Instructions::SLUG_STR, 7.0), - (L1Hits::SLUG_STR, 8.0), - (L2Hits::SLUG_STR, 9.0), - (RamHits::SLUG_STR, 10.0), - (TotalReadWrite::SLUG_STR, 11.0), - (EstimatedCycles::SLUG_STR, 12.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::bench::multiple_lines id:string with multiple\nlines\nand one more", - ); - } - } - - #[test] - fn name_multiple_lines_mixed() { - use gungraun::*; - - let results = convert_file_path::( - "./tool_output/rust/gungraun/name_on_multiple_lines_mixed.txt", - ); - - assert_eq!(results.inner.len(), 3); - - { - let mut expected = HashMap::new(); - - expected.extend([ - (Instructions::SLUG_STR, 1.0), - (L1Hits::SLUG_STR, 2.0), - (L2Hits::SLUG_STR, 3.0), - (RamHits::SLUG_STR, 4.0), - (TotalReadWrite::SLUG_STR, 5.0), - (EstimatedCycles::SLUG_STR, 6.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::bench::multiple_lines id:first with one line", - ); - } - - { - let mut expected = HashMap::new(); - - expected.extend([ - (Instructions::SLUG_STR, 7.0), - (L1Hits::SLUG_STR, 8.0), - (L2Hits::SLUG_STR, 9.0), - (RamHits::SLUG_STR, 10.0), - (TotalReadWrite::SLUG_STR, 11.0), - (EstimatedCycles::SLUG_STR, 12.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::bench::multiple_lines id:two\nlines", - ); - } - - { - let mut expected = HashMap::new(); - - expected.extend([ - (Instructions::SLUG_STR, 13.0), - (L1Hits::SLUG_STR, 14.0), - (L2Hits::SLUG_STR, 15.0), - (RamHits::SLUG_STR, 16.0), - (TotalReadWrite::SLUG_STR, 17.0), - (EstimatedCycles::SLUG_STR, 18.0), - ]); - - compare_benchmark( - &expected, - &results, - "rust_iai_callgrind::bench::multiple_lines id:last with one line", - ); - } - } - - #[derive(Default)] - pub struct OptionalMetrics { - pub global_bus_events: bool, - pub dhat: bool, - } - - pub fn validate_adapter_rust_gungraun( - results: &AdapterResults, - optional_metrics: &OptionalMetrics, - ) { - assert_eq!(results.inner.len(), 2); - - { - let mut expected = HashMap::new(); - - expected.extend([ - (gungraun::Instructions::SLUG_STR, 1_734.0), - (gungraun::L1Hits::SLUG_STR, 2_359.0), - (gungraun::L2Hits::SLUG_STR, 0.0), - (gungraun::RamHits::SLUG_STR, 3.0), - (gungraun::TotalReadWrite::SLUG_STR, 2_362.0), - (gungraun::EstimatedCycles::SLUG_STR, 2_464.0), - ]); - - if optional_metrics.global_bus_events { - expected.insert(gungraun::GlobalBusEvents::SLUG_STR, 2.0); - } - - if optional_metrics.dhat { - expected.extend([ - (gungraun::TotalBytes::SLUG_STR, 29_499.0), - (gungraun::TotalBlocks::SLUG_STR, 2_806.0), - (gungraun::AtTGmaxBytes::SLUG_STR, 378.0), - (gungraun::AtTGmaxBlocks::SLUG_STR, 34.0), - (gungraun::AtTEndBytes::SLUG_STR, 0.0), - (gungraun::AtTEndBlocks::SLUG_STR, 0.0), - (gungraun::ReadsBytes::SLUG_STR, 57_725.0), - (gungraun::WritesBytes::SLUG_STR, 73_810.0), - ]); - } - - compare_benchmark( - &expected, - results, - "rust_iai_callgrind::bench_fibonacci_group::bench_fibonacci short:10", - ); - } - - { - let mut expected = HashMap::new(); - - expected.extend([ - (gungraun::Instructions::SLUG_STR, 26_214_734.0), - (gungraun::L1Hits::SLUG_STR, 35_638_619.0), - (gungraun::L2Hits::SLUG_STR, 0.0), - (gungraun::RamHits::SLUG_STR, 3.0), - (gungraun::TotalReadWrite::SLUG_STR, 35_638_622.0), - (gungraun::EstimatedCycles::SLUG_STR, 35_638_724.0), - ]); - - if optional_metrics.global_bus_events { - expected.insert(gungraun::GlobalBusEvents::SLUG_STR, 10.0); - } - - if optional_metrics.dhat { - expected.extend([ - (gungraun::TotalBytes::SLUG_STR, 26_294_939.0), - (gungraun::TotalBlocks::SLUG_STR, 2_328_086.0), - (gungraun::AtTGmaxBytes::SLUG_STR, 933_718.0), - (gungraun::AtTGmaxBlocks::SLUG_STR, 18_344.0), - (gungraun::AtTEndBytes::SLUG_STR, 0.0), - (gungraun::AtTEndBlocks::SLUG_STR, 0.0), - (gungraun::ReadsBytes::SLUG_STR, 47_577_425.0), - (gungraun::WritesBytes::SLUG_STR, 37_733_810.0), - ]); - } - - compare_benchmark( - &expected, - results, - "rust_iai_callgrind::bench_fibonacci_group::bench_fibonacci long:30", - ); - } - } - - fn compare_benchmark( - expected: &HashMap<&str, f64>, - results: &AdapterResults, - benchmark_name: &str, - ) { - let actual = results.get(benchmark_name).unwrap(); - assert_eq!(actual.inner.len(), expected.len()); - - for (key, value) in expected { - let metric = actual.get(key).unwrap(); - assert_eq!(metric.value, OrderedFloat::from(*value)); - assert_eq!(metric.lower_value, None); - assert_eq!(metric.upper_value, None); - } - } } diff --git a/lib/bencher_adapter/src/adapters/rust/gungraun_stdout.rs b/lib/bencher_adapter/src/adapters/rust/gungraun_stdout.rs new file mode 100644 index 000000000..cc55b935f --- /dev/null +++ b/lib/bencher_adapter/src/adapters/rust/gungraun_stdout.rs @@ -0,0 +1,1216 @@ +use std::ops::Neg as _; + +use bencher_json::{ + BenchmarkName, JsonNewMetric, + project::{ + measure::built_in::{BuiltInMeasure as _, gungraun}, + report::JsonAverage, + }, +}; +use nom::{ + IResult, Parser, + branch::alt, + bytes::complete::{is_a, is_not, tag, take_until1}, + character::complete::{char, space0, space1}, + combinator::{map, opt, peek, recognize}, + error::Error, + multi::{many0, many1}, + sequence::{delimited, preceded, terminated}, +}; + +use crate::{ + Adaptable, Settings, + adapters::util::parse_f64, + results::adapter_results::{AdapterResults, GungraunMeasure}, +}; + +pub struct AdapterRustGungraunStdout; + +impl Adaptable for AdapterRustGungraunStdout { + fn parse(input: &str, settings: Settings) -> Option { + match settings.average { + None => {}, + Some(JsonAverage::Mean | JsonAverage::Median) => { + return None; // 'gungraun' results are for a single run only. + }, + } + + // Clean up the input by removing ANSI escape codes: + let input = strip_ansi_escapes::strip_str(input); + + let benchmarks = match multiple_benchmarks().parse(&*input) { + Err(error) => { + debug_assert!(false, "Error parsing input:\n{error:#?}"); + return None; + }, + Ok((remainder, benchmarks)) => { + debug_assert_eq!(remainder.len(), 0, "Unparsed trailing input:\n{remainder}"); + benchmarks + }, + }; + + AdapterResults::new_gungraun(benchmarks) + } +} + +fn multiple_benchmarks<'a>() +-> impl Parser<&'a str, Output = Vec<(BenchmarkName, Vec)>, Error = Error<&'a str>> +{ + map( + many0(alt(( + // Try to parse a single benchmark: + single_benchmark(), + // Otherwise, parse/ignore unrelated lines: + map(terminated(not_line_ending(), opt(line_ending())), |_| None), + // Otherwise, parse/ignore empty lines: + map(line_ending(), |_| None), + ))), + // Skip 'None' resulting from empty/unrelated lines: + |benchmarks| benchmarks.into_iter().flatten().collect(), + ) +} + +fn single_benchmark<'a>() +-> impl Parser<&'a str, Output = Option<(BenchmarkName, Vec)>, Error = Error<&'a str>> +{ + map( + ( + terminated( + recognize(( + is_not(":\r\n \t"), + tag("::"), + is_not(":\r\n \t"), + tag("::"), + not_benchmark_name_end(), + )), + benchmark_name_end(), + ), + many0(alt(( + // Callgrind tool if it was enabled: + callgrind_tool_measures(), + // Cachegrind tool if it was enabled: + cachegrind_tool_measures(), + // Add DHAT tool measures if it was enabled: + dhat_tool_measures(), + // Add Memcheck tool measures if it was enabled: + memcheck_tool_measures(), + // Add Helgrind tool measures if it was enabled: + helgrind_tool_measures(), + // Add Drd tool measures if it was enabled: + drd_tool_measures(), + ))), + ), + |(benchmark_name, measures)| { + // trim here to avoid loose `\r` chars at the end of the string because of the + // `not_benchmark_name_end` parser. It's maybe not a bad idea anyways. + let benchmark_name = benchmark_name.trim().parse().ok()?; + let measures = measures.into_iter().flatten().collect(); + + Some((benchmark_name, measures)) + }, + ) +} + +fn callgrind_tool_measures<'a>() +-> impl Parser<&'a str, Output = Vec, Error = Error<&'a str>> { + map( + preceded(opt(tool_name_line("CALLGRIND")), many1(metric_line())), + |metrics| { + metrics + .into_iter() + .map(|(metric_name, json)| match metric_name.as_str() { + gungraun::Instructions::NAME_STR => GungraunMeasure::Instructions(json), + gungraun::L1Hits::NAME_STR => GungraunMeasure::L1Hits(json), + gungraun::L2Hits::NAME_STR => GungraunMeasure::L2Hits(json), + gungraun::LLHits::NAME_STR => GungraunMeasure::LLHits(json), + gungraun::RamHits::NAME_STR => GungraunMeasure::RamHits(json), + gungraun::TotalReadWrite::NAME_STR => GungraunMeasure::TotalReadWrite(json), + gungraun::EstimatedCycles::NAME_STR => GungraunMeasure::EstimatedCycles(json), + gungraun::Dr::NAME_STR => GungraunMeasure::DataCacheReads(json), + gungraun::Dw::NAME_STR => GungraunMeasure::DataCacheWrites(json), + gungraun::I1mr::NAME_STR => GungraunMeasure::L1InstrCacheReadMisses(json), + gungraun::D1mr::NAME_STR => GungraunMeasure::L1DataCacheReadMisses(json), + gungraun::D1mw::NAME_STR => GungraunMeasure::L1DataCacheWriteMisses(json), + gungraun::ILmr::NAME_STR => GungraunMeasure::LLInstrCacheReadMisses(json), + gungraun::DLmr::NAME_STR => GungraunMeasure::LLDataCacheReadMisses(json), + gungraun::DLmw::NAME_STR => GungraunMeasure::LLDataCacheWriteMisses(json), + gungraun::I1MissRate::NAME_STR => GungraunMeasure::L1InstrCacheMissRate(json), + gungraun::LLiMissRate::NAME_STR => GungraunMeasure::LLInstrCacheMissRate(json), + gungraun::D1MissRate::NAME_STR => GungraunMeasure::L1DataCacheMissRate(json), + gungraun::LLdMissRate::NAME_STR => GungraunMeasure::LLDataCacheMissRate(json), + gungraun::LLMissRate::NAME_STR => GungraunMeasure::LLCacheMissRate(json), + gungraun::L1HitRate::NAME_STR => GungraunMeasure::L1HitRate(json), + gungraun::LLHitRate::NAME_STR => GungraunMeasure::LLHitRate(json), + gungraun::RamHitRate::NAME_STR => GungraunMeasure::RamHitRate(json), + gungraun::SysCount::NAME_STR => GungraunMeasure::NumberSystemCalls(json), + gungraun::SysTime::NAME_STR => GungraunMeasure::TimeSystemCalls(json), + gungraun::SysCpuTime::NAME_STR => GungraunMeasure::CpuTimeSystemCalls(json), + gungraun::GlobalBusEvents::NAME_STR => GungraunMeasure::GlobalBusEvents(json), + gungraun::Bc::NAME_STR => GungraunMeasure::ExecutedConditionalBranches(json), + gungraun::Bcm::NAME_STR => { + GungraunMeasure::MispredictedConditionalBranches(json) + }, + gungraun::Bi::NAME_STR => GungraunMeasure::ExecutedIndirectBranches(json), + gungraun::Bim::NAME_STR => GungraunMeasure::MispredictedIndirectBranches(json), + gungraun::ILdmr::NAME_STR => GungraunMeasure::DirtyMissInstructionRead(json), + gungraun::DLdmr::NAME_STR => GungraunMeasure::DirtyMissDataRead(json), + gungraun::DLdmw::NAME_STR => GungraunMeasure::DirtyMissDataWrite(json), + gungraun::AcCost1::NAME_STR => GungraunMeasure::L1BadTemporalLocality(json), + gungraun::AcCost2::NAME_STR => GungraunMeasure::LLBadTemporalLocality(json), + gungraun::SpLoss1::NAME_STR => GungraunMeasure::L1BadSpatialLocality(json), + gungraun::SpLoss2::NAME_STR => GungraunMeasure::LLBadSpatialLocality(json), + _ => GungraunMeasure::Unknown, + }) + .collect() + }, + ) +} + +fn cachegrind_tool_measures<'a>() +-> impl Parser<&'a str, Output = Vec, Error = Error<&'a str>> { + map( + preceded(tool_name_line("CACHEGRIND"), many1(metric_line())), + |metrics| { + metrics + .into_iter() + .map(|(metric_name, json)| match metric_name.as_str() { + gungraun::Instructions::NAME_STR => GungraunMeasure::Instructions(json), + gungraun::L1Hits::NAME_STR => GungraunMeasure::L1Hits(json), + gungraun::L2Hits::NAME_STR => GungraunMeasure::L2Hits(json), + gungraun::LLHits::NAME_STR => GungraunMeasure::LLHits(json), + gungraun::RamHits::NAME_STR => GungraunMeasure::RamHits(json), + gungraun::TotalReadWrite::NAME_STR => GungraunMeasure::TotalReadWrite(json), + gungraun::EstimatedCycles::NAME_STR => GungraunMeasure::EstimatedCycles(json), + gungraun::Dr::NAME_STR => GungraunMeasure::DataCacheReads(json), + gungraun::Dw::NAME_STR => GungraunMeasure::DataCacheWrites(json), + gungraun::I1mr::NAME_STR => GungraunMeasure::L1InstrCacheReadMisses(json), + gungraun::D1mr::NAME_STR => GungraunMeasure::L1DataCacheReadMisses(json), + gungraun::D1mw::NAME_STR => GungraunMeasure::L1DataCacheWriteMisses(json), + gungraun::ILmr::NAME_STR => GungraunMeasure::LLInstrCacheReadMisses(json), + gungraun::DLmr::NAME_STR => GungraunMeasure::LLDataCacheReadMisses(json), + gungraun::DLmw::NAME_STR => GungraunMeasure::LLDataCacheWriteMisses(json), + gungraun::I1MissRate::NAME_STR => GungraunMeasure::L1InstrCacheMissRate(json), + gungraun::LLiMissRate::NAME_STR => GungraunMeasure::LLInstrCacheMissRate(json), + gungraun::D1MissRate::NAME_STR => GungraunMeasure::L1DataCacheMissRate(json), + gungraun::LLdMissRate::NAME_STR => GungraunMeasure::LLDataCacheMissRate(json), + gungraun::LLMissRate::NAME_STR => GungraunMeasure::LLCacheMissRate(json), + gungraun::L1HitRate::NAME_STR => GungraunMeasure::L1HitRate(json), + gungraun::LLHitRate::NAME_STR => GungraunMeasure::LLHitRate(json), + gungraun::RamHitRate::NAME_STR => GungraunMeasure::RamHitRate(json), + _ => GungraunMeasure::Unknown, + }) + .collect() + }, + ) +} + +fn dhat_tool_measures<'a>() +-> impl Parser<&'a str, Output = Vec, Error = Error<&'a str>> { + map( + preceded(tool_name_line("DHAT"), many1(metric_line())), + |metrics| { + metrics + .into_iter() + .map(|(metric_name, json)| match metric_name.as_str() { + gungraun::TotalBytes::NAME_STR => GungraunMeasure::TotalBytes(json), + gungraun::TotalBlocks::NAME_STR => GungraunMeasure::TotalBlocks(json), + gungraun::TotalUnits::NAME_STR => GungraunMeasure::TotalUnits(json), + gungraun::TotalEvents::NAME_STR => GungraunMeasure::TotalEvents(json), + gungraun::TotalLifetimes::NAME_STR => GungraunMeasure::TotalLifetimes(json), + gungraun::AtTGmaxBytes::NAME_STR => GungraunMeasure::AtTGmaxBytes(json), + gungraun::AtTGmaxBlocks::NAME_STR => GungraunMeasure::AtTGmaxBlocks(json), + gungraun::AtTEndBytes::NAME_STR => GungraunMeasure::AtTEndBytes(json), + gungraun::AtTEndBlocks::NAME_STR => GungraunMeasure::AtTEndBlocks(json), + gungraun::ReadsBytes::NAME_STR => GungraunMeasure::ReadsBytes(json), + gungraun::WritesBytes::NAME_STR => GungraunMeasure::WritesBytes(json), + gungraun::MaximumBytes::NAME_STR => GungraunMeasure::MaximumBytes(json), + gungraun::MaximumBlocks::NAME_STR => GungraunMeasure::MaximumBlocks(json), + _ => GungraunMeasure::Unknown, + }) + .collect() + }, + ) +} + +fn memcheck_tool_measures<'a>() +-> impl Parser<&'a str, Output = Vec, Error = Error<&'a str>> { + map( + preceded(tool_name_line("MEMCHECK"), many1(metric_line())), + |metrics| { + metrics + .into_iter() + .map(|(metric_name, json)| match metric_name.as_str() { + gungraun::MemcheckErrors::NAME_STR => GungraunMeasure::MemcheckErrors(json), + gungraun::MemcheckContexts::NAME_STR => GungraunMeasure::MemcheckContexts(json), + gungraun::MemcheckSuppressedErrors::NAME_STR => { + GungraunMeasure::MemcheckSuppressedErrors(json) + }, + gungraun::MemcheckSuppressedContexts::NAME_STR => { + GungraunMeasure::MemcheckSuppressedContexts(json) + }, + _ => GungraunMeasure::Unknown, + }) + .collect() + }, + ) +} + +fn helgrind_tool_measures<'a>() +-> impl Parser<&'a str, Output = Vec, Error = Error<&'a str>> { + map( + preceded(tool_name_line("HELGRIND"), many1(metric_line())), + |metrics| { + metrics + .into_iter() + .map(|(metric_name, json)| match metric_name.as_str() { + gungraun::HelgrindErrors::NAME_STR => GungraunMeasure::HelgrindErrors(json), + gungraun::HelgrindContexts::NAME_STR => GungraunMeasure::HelgrindContexts(json), + gungraun::HelgrindSuppressedErrors::NAME_STR => { + GungraunMeasure::HelgrindSuppressedErrors(json) + }, + gungraun::HelgrindSuppressedContexts::NAME_STR => { + GungraunMeasure::HelgrindSuppressedContexts(json) + }, + _ => GungraunMeasure::Unknown, + }) + .collect() + }, + ) +} + +fn drd_tool_measures<'a>() +-> impl Parser<&'a str, Output = Vec, Error = Error<&'a str>> { + map( + preceded(tool_name_line("DRD"), many1(metric_line())), + |metrics| { + metrics + .into_iter() + .map(|(metric_name, json)| match metric_name.as_str() { + gungraun::DrdErrors::NAME_STR => GungraunMeasure::DrdErrors(json), + gungraun::DrdContexts::NAME_STR => GungraunMeasure::DrdContexts(json), + gungraun::DrdSuppressedErrors::NAME_STR => { + GungraunMeasure::DrdSuppressedErrors(json) + }, + gungraun::DrdSuppressedContexts::NAME_STR => { + GungraunMeasure::DrdSuppressedContexts(json) + }, + _ => GungraunMeasure::Unknown, + }) + .collect() + }, + ) +} + +fn tool_name_line<'a>( + tool_name: &'static str, +) -> impl Parser<&'a str, Output = &'a str, Error = Error<&'a str>> { + delimited( + (space1, many1(tag("=")), tag(" ")), + tag(tool_name), + (tag(" "), many1(tag("=")), line_ending()), + ) +} + +fn metric_line<'a>() +-> impl Parser<&'a str, Output = (String, JsonNewMetric), Error = Error<&'a str>> { + map( + ( + space1, + is_not(":\r\n"), + char(':'), + space1, + // the current run value: + parse_f64, + char('|'), + alt(( + // No previous run: + recognize(( + tag("N/A"), + space1, + delimited(char('('), many1(char('*')), char(')')), + )), + // Comparison to previous run: + recognize(( + parse_f64, + space0, + alt(( + recognize(delimited(char('('), tag("No change"), char(')'))), + recognize(( + delimited(char('('), alt((infinity, percent)), char(')')), + space1, + delimited(char('['), alt((infinity, factor)), char(']')), + )), + )), + )), + )), + line_ending(), + ), + |(_, metric_name, _, _, current_value, _, _, _)| { + ( + metric_name.to_owned(), + JsonNewMetric { + value: current_value.into(), + lower_value: None, + upper_value: None, + }, + ) + }, + ) +} + +fn infinity(input: &str) -> IResult<&str, f64> { + map( + ( + alt((many1(char('+')), many1(char('-')))), + tag("inf"), + alt((many1(char('+')), many1(char('-')))), + ), + |(signs, _, _)| { + // The indexing is safe due to the usage of `many1` above + #[expect(clippy::indexing_slicing, reason = "many1 guarantees non-empty vec")] + let sign = signs[0]; + if sign == '+' { + f64::INFINITY + } else { + f64::NEG_INFINITY + } + }, + ) + .parse(input) +} + +fn factor(input: &str) -> IResult<&str, f64> { + map( + (alt((char('+'), char('-'))), parse_f64, char('x')), + |(sign, num, _)| { + if sign == '+' { num } else { num.neg() } + }, + ) + .parse(input) +} + +fn percent(input: &str) -> IResult<&str, f64> { + map( + (alt((char('+'), char('-'))), parse_f64, char('%')), + |(sign, num, _)| { + if sign == '+' { num } else { num.neg() } + }, + ) + .parse(input) +} + +fn line_ending<'a>() -> impl Parser<&'a str, Output = &'a str, Error = Error<&'a str>> { + is_a("\r\n") +} + +fn not_line_ending<'a>() -> impl Parser<&'a str, Output = &'a str, Error = Error<&'a str>> { + // Note: `not(line_ending)` doesn't work here, as it won't consume the matched characters + is_not("\r\n") +} + +/// Parser that matches the benchmark name ending sequence, excluding the two spaces +fn benchmark_name_end<'a>() +-> impl Parser<&'a str, Output = (&'a str, &'a str), Error = Error<&'a str>> { + // we only peek here so the `metric_line` parser can match the first spaces too + (line_ending(), peek(tag(" "))) +} + +/// A parser that matches input until it encounters the benchmark name end sequence. +/// +/// Similar to the `benchmark_name_end` parser, this parser addresses an unusual behavior in +/// `gungraun` (iai-callgrind) by allowing benchmark names to span multiple lines. While this +/// behavior is not a bug in `gungraun`, it deviates from the original intent. If there are multiple +/// lines they don't start with two spaces, so we can use that as test for the end of the benchmark +/// name. +fn not_benchmark_name_end<'a>() -> impl Parser<&'a str, Output = &'a str, Error = Error<&'a str>> { + // Ignore the `\r\n` possibility here and instead trim the benchmark name later + take_until1("\n ") +} + +#[cfg(test)] +pub(crate) mod test_rust_gungraun_stdout { + use crate::{AdapterResults, adapters::test_util::convert_file_path}; + use bencher_json::project::measure::built_in::{BuiltInMeasure as _, gungraun}; + use ordered_float::OrderedFloat; + use pretty_assertions::assert_eq; + + use super::AdapterRustGungraunStdout; + use std::collections::HashMap; + + #[test] + fn without_optional_metrics() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/without-optional-metrics.txt", + ); + + validate_adapter_rust_gungraun_stdout(&results, &OptionalMetrics::default()); + } + + #[test] + fn with_dhat() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/with-dhat.txt", + ); + + validate_adapter_rust_gungraun_stdout( + &results, + &OptionalMetrics { + dhat: true, + ..Default::default() + }, + ); + } + + #[test] + fn with_dhat_first_then_callgrind() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/dhat-then-callgrind.txt", + ); + + validate_adapter_rust_gungraun_stdout( + &results, + &OptionalMetrics { + dhat: true, + ..Default::default() + }, + ); + } + + #[test] + fn with_dhat_and_global_bus_events() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/with-dhat-and-global-bus-events.txt", + ); + + validate_adapter_rust_gungraun_stdout( + &results, + &OptionalMetrics { + dhat: true, + global_bus_events: true, + }, + ); + } + + #[test] + fn delta() { + let results = + convert_file_path::("./tool_output/rust/gungraun/delta.txt"); + + validate_adapter_rust_gungraun_stdout(&results, &OptionalMetrics::default()); + } + + #[test] + fn delta_with_infinity() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/delta_with_inf.txt", + ); + + assert_eq!(results.inner.len(), 2); + + { + let expected = HashMap::from([ + (gungraun::Instructions::SLUG_STR, 1_734.0), + (gungraun::L1Hits::SLUG_STR, 2_359.0), + (gungraun::L2Hits::SLUG_STR, 0.0), + (gungraun::RamHits::SLUG_STR, 3.0), + (gungraun::TotalReadWrite::SLUG_STR, 0.0), + (gungraun::EstimatedCycles::SLUG_STR, 2_464.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::bench_fibonacci_group::bench_fibonacci short:10", + ); + } + + { + let expected = HashMap::from([ + (gungraun::Instructions::SLUG_STR, 26_214_734.0), + (gungraun::L1Hits::SLUG_STR, 35_638_619.0), + (gungraun::L2Hits::SLUG_STR, 0.0), + (gungraun::RamHits::SLUG_STR, 3.0), + (gungraun::TotalReadWrite::SLUG_STR, 35_638_622.0), + (gungraun::EstimatedCycles::SLUG_STR, 35_638_724.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::bench_fibonacci_group::bench_fibonacci long:30", + ); + } + } + + #[test] + fn with_summary_and_regressions() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/with-summary-and-regressions.txt", + ); + + validate_adapter_rust_gungraun_stdout(&results, &OptionalMetrics::default()); + } + + #[test] + fn with_gungraun_summary() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/with-gungraun-summary.txt", + ); + + validate_adapter_rust_gungraun_stdout(&results, &OptionalMetrics::default()); + } + + #[test] + fn ansi_escapes_issue_345() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/ansi-escapes.txt", + ); + + validate_adapter_rust_gungraun_stdout(&results, &OptionalMetrics::default()); + } + + #[test] + fn with_ge() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/with-ge.txt", + ); + + validate_adapter_rust_gungraun_stdout( + &results, + &OptionalMetrics { + global_bus_events: true, + ..Default::default() + }, + ); + } + + #[test] + fn without_cachesim() { + use gungraun::*; + + let results = convert_file_path::( + "./tool_output/rust/gungraun/without-cachesim.txt", + ); + + assert_eq!(results.inner.len(), 2); + + { + let expected = HashMap::from([(Instructions::SLUG_STR, 1734.0)]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::bench_fibonacci_group::bench_fibonacci short:10", + ); + } + + { + let expected = HashMap::from([(Instructions::SLUG_STR, 26_214_734.0)]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::bench_fibonacci_group::bench_fibonacci long:30", + ); + } + } + + #[test] + fn callgrind_mixed_order() { + use gungraun::*; + + let results = convert_file_path::( + "./tool_output/rust/gungraun/callgrind-mixed-order.txt", + ); + + assert_eq!(results.inner.len(), 2); + + let expected = HashMap::from([ + (Instructions::SLUG_STR, 1.0), + (Dr::SLUG_STR, 2.0), + (Dw::SLUG_STR, 3.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::callgrind_format mixed_1", + ); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::callgrind_format mixed_2", + ); + } + + #[test] + fn callgrind_ll_hits() { + use gungraun::*; + + let results = convert_file_path::( + "./tool_output/rust/gungraun/callgrind-ll-hits.txt", + ); + + assert_eq!(results.inner.len(), 2); + + { + let expected = + HashMap::from([(Instructions::SLUG_STR, 10.0), (LLHits::SLUG_STR, 20.0)]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::callgrind_format ll_hits", + ); + } + + { + let expected = HashMap::from([(Instructions::SLUG_STR, 1.0), (LLHits::SLUG_STR, 2.0)]); + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::callgrind_format ll_hits_mixed", + ); + } + } + + #[test] + fn callgrind_all() { + use gungraun::*; + + let results = convert_file_path::( + "./tool_output/rust/gungraun/callgrind-all.txt", + ); + + assert_eq!(results.inner.len(), 2); + + { + let expected = HashMap::from([ + (Instructions::SLUG_STR, 1.0), + (Dr::SLUG_STR, 2.0), + (Dw::SLUG_STR, 3.0), + (I1mr::SLUG_STR, 4.0), + (D1mr::SLUG_STR, 5.0), + (D1mw::SLUG_STR, 6.0), + (ILmr::SLUG_STR, 7.0), + (DLmr::SLUG_STR, 8.0), + (DLmw::SLUG_STR, 9.0), + (I1MissRate::SLUG_STR, 10.0), + (LLiMissRate::SLUG_STR, 11.0), + (D1MissRate::SLUG_STR, 12.0), + (LLdMissRate::SLUG_STR, 13.0), + (LLMissRate::SLUG_STR, 14.0), + (L1Hits::SLUG_STR, 15.0), + (L2Hits::SLUG_STR, 16.0), + (RamHits::SLUG_STR, 17.0), + (L1HitRate::SLUG_STR, 18.0), + (LLHitRate::SLUG_STR, 19.0), + (RamHitRate::SLUG_STR, 20.0), + (TotalReadWrite::SLUG_STR, 21.0), + (EstimatedCycles::SLUG_STR, 22.0), + (SysCount::SLUG_STR, 23.0), + (SysTime::SLUG_STR, 24.0), + (SysCpuTime::SLUG_STR, 25.0), + (GlobalBusEvents::SLUG_STR, 26.0), + (Bc::SLUG_STR, 27.0), + (Bcm::SLUG_STR, 28.0), + (Bi::SLUG_STR, 29.0), + (Bim::SLUG_STR, 30.0), + (ILdmr::SLUG_STR, 31.0), + (DLdmr::SLUG_STR, 32.0), + (DLdmw::SLUG_STR, 33.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::callgrind_format all_with_wb", + ); + } + + { + let expected = HashMap::from([ + (Instructions::SLUG_STR, 1.0), + (Dr::SLUG_STR, 2.0), + (Dw::SLUG_STR, 3.0), + (I1mr::SLUG_STR, 4.0), + (D1mr::SLUG_STR, 5.0), + (D1mw::SLUG_STR, 6.0), + (ILmr::SLUG_STR, 7.0), + (DLmr::SLUG_STR, 8.0), + (DLmw::SLUG_STR, 9.0), + (I1MissRate::SLUG_STR, 10.0), + (LLiMissRate::SLUG_STR, 11.0), + (D1MissRate::SLUG_STR, 12.0), + (LLdMissRate::SLUG_STR, 13.0), + (LLMissRate::SLUG_STR, 14.0), + (L1Hits::SLUG_STR, 15.0), + (L2Hits::SLUG_STR, 16.0), + (RamHits::SLUG_STR, 17.0), + (L1HitRate::SLUG_STR, 18.0), + (LLHitRate::SLUG_STR, 19.0), + (RamHitRate::SLUG_STR, 20.0), + (TotalReadWrite::SLUG_STR, 21.0), + (EstimatedCycles::SLUG_STR, 22.0), + (SysCount::SLUG_STR, 23.0), + (SysTime::SLUG_STR, 24.0), + (SysCpuTime::SLUG_STR, 25.0), + (GlobalBusEvents::SLUG_STR, 26.0), + (Bc::SLUG_STR, 27.0), + (Bcm::SLUG_STR, 28.0), + (Bi::SLUG_STR, 29.0), + (Bim::SLUG_STR, 30.0), + (AcCost1::SLUG_STR, 31.0), + (AcCost2::SLUG_STR, 32.0), + (SpLoss1::SLUG_STR, 33.0), + (SpLoss2::SLUG_STR, 34.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::callgrind_format all_with_cachuse", + ); + } + } + + #[test] + fn cachegrind() { + use gungraun::*; + + let results = convert_file_path::( + "./tool_output/rust/gungraun/cachegrind.txt", + ); + + assert_eq!(results.inner.len(), 3); + + { + let expected = HashMap::from([(Instructions::SLUG_STR, 1.0)]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::cachegrind_format just_instructions", + ); + } + + { + let expected = HashMap::from([ + (I1MissRate::SLUG_STR, 1.0), + (Dr::SLUG_STR, 2.0), + (EstimatedCycles::SLUG_STR, 3.0), + (TotalReadWrite::SLUG_STR, 4.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::cachegrind_format metrics_mixed", + ); + } + + { + let expected = HashMap::from([ + (Instructions::SLUG_STR, 1.0), + (Dr::SLUG_STR, 2.0), + (Dw::SLUG_STR, 3.0), + (I1mr::SLUG_STR, 4.0), + (D1mr::SLUG_STR, 5.0), + (D1mw::SLUG_STR, 6.0), + (ILmr::SLUG_STR, 7.0), + (DLmr::SLUG_STR, 8.0), + (DLmw::SLUG_STR, 9.0), + (I1MissRate::SLUG_STR, 10.0), + (LLiMissRate::SLUG_STR, 11.0), + (D1MissRate::SLUG_STR, 12.0), + (LLdMissRate::SLUG_STR, 13.0), + (LLMissRate::SLUG_STR, 14.0), + (L1Hits::SLUG_STR, 15.0), + (L2Hits::SLUG_STR, 16.0), + (RamHits::SLUG_STR, 17.0), + (L1HitRate::SLUG_STR, 18.0), + (LLHitRate::SLUG_STR, 19.0), + (RamHitRate::SLUG_STR, 20.0), + (TotalReadWrite::SLUG_STR, 21.0), + (EstimatedCycles::SLUG_STR, 22.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::cachegrind_format all_metrics", + ); + } + } + + #[test] + fn memcheck() { + use gungraun::*; + + let results = convert_file_path::( + "./tool_output/rust/gungraun/memcheck.txt", + ); + + assert_eq!(results.inner.len(), 3); + + { + let expected = HashMap::from([(MemcheckErrors::SLUG_STR, 1.0)]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::memcheck_format just_errors", + ); + } + + { + let expected = HashMap::from([ + (MemcheckContexts::SLUG_STR, 1.0), + (MemcheckSuppressedContexts::SLUG_STR, 2.0), + (MemcheckSuppressedErrors::SLUG_STR, 3.0), + (MemcheckErrors::SLUG_STR, 4.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::memcheck_format metrics_mixed", + ); + } + + { + let expected = HashMap::from([ + (MemcheckErrors::SLUG_STR, 1.0), + (MemcheckContexts::SLUG_STR, 2.0), + (MemcheckSuppressedErrors::SLUG_STR, 3.0), + (MemcheckSuppressedContexts::SLUG_STR, 4.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::memcheck_format all_metrics", + ); + } + } + + #[test] + fn helgrind() { + use gungraun::*; + + let results = convert_file_path::( + "./tool_output/rust/gungraun/helgrind.txt", + ); + + assert_eq!(results.inner.len(), 3); + + { + let expected = HashMap::from([(HelgrindErrors::SLUG_STR, 1.0)]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::helgrind_format just_errors", + ); + } + + { + let expected = HashMap::from([ + (HelgrindContexts::SLUG_STR, 1.0), + (HelgrindSuppressedContexts::SLUG_STR, 2.0), + (HelgrindSuppressedErrors::SLUG_STR, 3.0), + (HelgrindErrors::SLUG_STR, 4.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::helgrind_format metrics_mixed", + ); + } + + { + let expected = HashMap::from([ + (HelgrindErrors::SLUG_STR, 1.0), + (HelgrindContexts::SLUG_STR, 2.0), + (HelgrindSuppressedErrors::SLUG_STR, 3.0), + (HelgrindSuppressedContexts::SLUG_STR, 4.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::helgrind_format all_metrics", + ); + } + } + + #[test] + fn drd() { + use gungraun::*; + + let results = + convert_file_path::("./tool_output/rust/gungraun/drd.txt"); + + assert_eq!(results.inner.len(), 3); + + { + let expected = HashMap::from([(DrdErrors::SLUG_STR, 1.0)]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::drd_format just_errors", + ); + } + + { + let expected = HashMap::from([ + (DrdContexts::SLUG_STR, 1.0), + (DrdSuppressedContexts::SLUG_STR, 2.0), + (DrdSuppressedErrors::SLUG_STR, 3.0), + (DrdErrors::SLUG_STR, 4.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::drd_format metrics_mixed", + ); + } + + { + let expected = HashMap::from([ + (DrdErrors::SLUG_STR, 1.0), + (DrdContexts::SLUG_STR, 2.0), + (DrdSuppressedErrors::SLUG_STR, 3.0), + (DrdSuppressedContexts::SLUG_STR, 4.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::custom_format::drd_format all_metrics", + ); + } + } + + #[test] + fn name_multiple_lines() { + use gungraun::*; + + let results = convert_file_path::( + "./tool_output/rust/gungraun/name_on_multiple_lines.txt", + ); + + assert_eq!(results.inner.len(), 2); + + { + let mut expected = HashMap::new(); + + expected.extend([ + (Instructions::SLUG_STR, 1.0), + (L1Hits::SLUG_STR, 2.0), + (L2Hits::SLUG_STR, 3.0), + (RamHits::SLUG_STR, 4.0), + (TotalReadWrite::SLUG_STR, 5.0), + (EstimatedCycles::SLUG_STR, 6.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::bench::multiple_lines id:string with two\nlines", + ); + } + + { + let mut expected = HashMap::new(); + + expected.extend([ + (Instructions::SLUG_STR, 7.0), + (L1Hits::SLUG_STR, 8.0), + (L2Hits::SLUG_STR, 9.0), + (RamHits::SLUG_STR, 10.0), + (TotalReadWrite::SLUG_STR, 11.0), + (EstimatedCycles::SLUG_STR, 12.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::bench::multiple_lines id:string with multiple\nlines\nand one more", + ); + } + } + + #[test] + fn name_multiple_lines_mixed() { + use gungraun::*; + + let results = convert_file_path::( + "./tool_output/rust/gungraun/name_on_multiple_lines_mixed.txt", + ); + + assert_eq!(results.inner.len(), 3); + + { + let mut expected = HashMap::new(); + + expected.extend([ + (Instructions::SLUG_STR, 1.0), + (L1Hits::SLUG_STR, 2.0), + (L2Hits::SLUG_STR, 3.0), + (RamHits::SLUG_STR, 4.0), + (TotalReadWrite::SLUG_STR, 5.0), + (EstimatedCycles::SLUG_STR, 6.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::bench::multiple_lines id:first with one line", + ); + } + + { + let mut expected = HashMap::new(); + + expected.extend([ + (Instructions::SLUG_STR, 7.0), + (L1Hits::SLUG_STR, 8.0), + (L2Hits::SLUG_STR, 9.0), + (RamHits::SLUG_STR, 10.0), + (TotalReadWrite::SLUG_STR, 11.0), + (EstimatedCycles::SLUG_STR, 12.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::bench::multiple_lines id:two\nlines", + ); + } + + { + let mut expected = HashMap::new(); + + expected.extend([ + (Instructions::SLUG_STR, 13.0), + (L1Hits::SLUG_STR, 14.0), + (L2Hits::SLUG_STR, 15.0), + (RamHits::SLUG_STR, 16.0), + (TotalReadWrite::SLUG_STR, 17.0), + (EstimatedCycles::SLUG_STR, 18.0), + ]); + + compare_benchmark( + &expected, + &results, + "rust_iai_callgrind::bench::multiple_lines id:last with one line", + ); + } + } + + #[derive(Default)] + pub struct OptionalMetrics { + pub global_bus_events: bool, + pub dhat: bool, + } + + pub fn validate_adapter_rust_gungraun_stdout( + results: &AdapterResults, + optional_metrics: &OptionalMetrics, + ) { + assert_eq!(results.inner.len(), 2); + + { + let mut expected = HashMap::new(); + + expected.extend([ + (gungraun::Instructions::SLUG_STR, 1_734.0), + (gungraun::L1Hits::SLUG_STR, 2_359.0), + (gungraun::L2Hits::SLUG_STR, 0.0), + (gungraun::RamHits::SLUG_STR, 3.0), + (gungraun::TotalReadWrite::SLUG_STR, 2_362.0), + (gungraun::EstimatedCycles::SLUG_STR, 2_464.0), + ]); + + if optional_metrics.global_bus_events { + expected.insert(gungraun::GlobalBusEvents::SLUG_STR, 2.0); + } + + if optional_metrics.dhat { + expected.extend([ + (gungraun::TotalBytes::SLUG_STR, 29_499.0), + (gungraun::TotalBlocks::SLUG_STR, 2_806.0), + (gungraun::AtTGmaxBytes::SLUG_STR, 378.0), + (gungraun::AtTGmaxBlocks::SLUG_STR, 34.0), + (gungraun::AtTEndBytes::SLUG_STR, 0.0), + (gungraun::AtTEndBlocks::SLUG_STR, 0.0), + (gungraun::ReadsBytes::SLUG_STR, 57_725.0), + (gungraun::WritesBytes::SLUG_STR, 73_810.0), + ]); + } + + compare_benchmark( + &expected, + results, + "rust_iai_callgrind::bench_fibonacci_group::bench_fibonacci short:10", + ); + } + + { + let mut expected = HashMap::new(); + + expected.extend([ + (gungraun::Instructions::SLUG_STR, 26_214_734.0), + (gungraun::L1Hits::SLUG_STR, 35_638_619.0), + (gungraun::L2Hits::SLUG_STR, 0.0), + (gungraun::RamHits::SLUG_STR, 3.0), + (gungraun::TotalReadWrite::SLUG_STR, 35_638_622.0), + (gungraun::EstimatedCycles::SLUG_STR, 35_638_724.0), + ]); + + if optional_metrics.global_bus_events { + expected.insert(gungraun::GlobalBusEvents::SLUG_STR, 10.0); + } + + if optional_metrics.dhat { + expected.extend([ + (gungraun::TotalBytes::SLUG_STR, 26_294_939.0), + (gungraun::TotalBlocks::SLUG_STR, 2_328_086.0), + (gungraun::AtTGmaxBytes::SLUG_STR, 933_718.0), + (gungraun::AtTGmaxBlocks::SLUG_STR, 18_344.0), + (gungraun::AtTEndBytes::SLUG_STR, 0.0), + (gungraun::AtTEndBlocks::SLUG_STR, 0.0), + (gungraun::ReadsBytes::SLUG_STR, 47_577_425.0), + (gungraun::WritesBytes::SLUG_STR, 37_733_810.0), + ]); + } + + compare_benchmark( + &expected, + results, + "rust_iai_callgrind::bench_fibonacci_group::bench_fibonacci long:30", + ); + } + } + + fn compare_benchmark( + expected: &HashMap<&str, f64>, + results: &AdapterResults, + benchmark_name: &str, + ) { + let actual = results.get(benchmark_name).unwrap(); + assert_eq!(actual.inner.len(), expected.len()); + + for (key, value) in expected { + let metric = actual.get(key).unwrap(); + assert_eq!(metric.value, OrderedFloat::from(*value)); + assert_eq!(metric.lower_value, None); + assert_eq!(metric.upper_value, None); + } + } +} diff --git a/lib/bencher_adapter/src/adapters/rust/mod.rs b/lib/bencher_adapter/src/adapters/rust/mod.rs index 3acc1d422..48c5ef21d 100644 --- a/lib/bencher_adapter/src/adapters/rust/mod.rs +++ b/lib/bencher_adapter/src/adapters/rust/mod.rs @@ -2,12 +2,10 @@ pub mod bench; pub mod criterion; pub mod gungraun; pub mod gungraun_json; +pub mod gungraun_stdout; pub mod iai; -use self::{ - criterion::AdapterRustCriterion, gungraun::AdapterRustGungraun, - gungraun_json::AdapterRustGungraunJson, iai::AdapterRustIai, -}; +use self::{criterion::AdapterRustCriterion, gungraun::AdapterRustGungraun, iai::AdapterRustIai}; use crate::{Adaptable, AdapterResults, Settings}; use bench::AdapterRustBench; @@ -19,7 +17,6 @@ impl Adaptable for AdapterRust { .or_else(|| AdapterRustCriterion::parse(input, settings)) .or_else(|| AdapterRustIai::parse(input, settings)) .or_else(|| AdapterRustGungraun::parse(input, settings)) - .or_else(|| AdapterRustGungraunJson::parse(input, settings)) } } @@ -28,8 +25,9 @@ mod test_rust { use super::AdapterRust; use crate::adapters::{ rust::{ - bench::test_rust_bench, criterion::test_rust_criterion, gungraun::test_rust_gungraun, - gungraun_json::test_rust_gungraun_json, iai::test_rust_iai, + bench::test_rust_bench, criterion::test_rust_criterion, + gungraun_json::test_rust_gungraun_json, gungraun_stdout::test_rust_gungraun_stdout, + iai::test_rust_iai, }, test_util::convert_file_path, }; @@ -54,24 +52,23 @@ mod test_rust { #[test] fn adapter_rust_gungraun() { - let results = convert_file_path::( - "./tool_output/rust/gungraun/without-optional-metrics.txt", - ); + { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_callgrind_diff.txt", + ); - test_rust_gungraun::validate_adapter_rust_gungraun( - &results, - &test_rust_gungraun::OptionalMetrics::default(), - ); - } - - #[test] - fn adapter_rust_gungraun_json() { - let results = convert_file_path::( - "./tool_output/rust/gungraun/json_one_callgrind_diff.txt", - ); + test_rust_gungraun_json::validate_adapter_rust_gungraun_json(&results); + } - dbg!(&results); + { + let results = convert_file_path::( + "./tool_output/rust/gungraun/without-optional-metrics.txt", + ); - test_rust_gungraun_json::validate_adapter_rust_gungraun_json(&results); + test_rust_gungraun_stdout::validate_adapter_rust_gungraun_stdout( + &results, + &test_rust_gungraun_stdout::OptionalMetrics::default(), + ); + } } } diff --git a/lib/bencher_adapter/src/lib.rs b/lib/bencher_adapter/src/lib.rs index c96e25781..3fa538be8 100644 --- a/lib/bencher_adapter/src/lib.rs +++ b/lib/bencher_adapter/src/lib.rs @@ -18,7 +18,8 @@ use adapters::{ ruby::{AdapterRuby, benchmark::AdapterRubyBenchmark}, rust::{ AdapterRust, bench::AdapterRustBench, criterion::AdapterRustCriterion, - gungraun::AdapterRustGungraun, gungraun_json::AdapterRustGungraunJson, iai::AdapterRustIai, + gungraun_json::AdapterRustGungraunJson, gungraun_stdout::AdapterRustGungraunStdout, + iai::AdapterRustIai, }, shell::{AdapterShell, hyperfine::AdapterShellHyperfine}, }; @@ -27,6 +28,8 @@ pub use bencher_json::{BenchmarkName, JsonNewMetric}; pub use error::AdapterError; pub use results::{AdapterResultsArray, adapter_results::AdapterResults}; +use crate::adapters::rust::gungraun::AdapterRustGungraun; + pub trait Adaptable { fn convert(&self, input: &str, settings: Settings) -> Option { Self::parse(input, settings) @@ -66,6 +69,7 @@ impl Adaptable for Adapter { Adapter::RustIai => AdapterRustIai::parse(input, settings), Adapter::RustGungraun => AdapterRustGungraun::parse(input, settings), Adapter::RustGungraunJson => AdapterRustGungraunJson::parse(input, settings), + Adapter::RustGungraunStdout => AdapterRustGungraunStdout::parse(input, settings), Adapter::Shell => AdapterShell::parse(input, settings), Adapter::ShellHyperfine => AdapterShellHyperfine::parse(input, settings), } diff --git a/lib/bencher_json/src/project/report.rs b/lib/bencher_json/src/project/report.rs index 9d74e2c92..014ea2361 100644 --- a/lib/bencher_json/src/project/report.rs +++ b/lib/bencher_json/src/project/report.rs @@ -91,6 +91,7 @@ const RUST_CRITERION_INT: i32 = 22; const RUST_IAI_INT: i32 = 23; const RUST_GUNGRAUN_INT: i32 = 24; const RUST_GUNGRAUN_JSON_INT: i32 = 25; +const RUST_GUNGRAUN_STDOUT_INT: i32 = 26; const CPP_INT: i32 = 30; const CPP_GOOGLE_INT: i32 = 31; const CPP_CATCH2_INT: i32 = 32; @@ -134,6 +135,7 @@ pub enum Adapter { #[serde(alias = "rust_iai_callgrind")] RustGungraun = RUST_GUNGRAUN_INT, RustGungraunJson = RUST_GUNGRAUN_JSON_INT, + RustGungraunStdout = RUST_GUNGRAUN_STDOUT_INT, Cpp = CPP_INT, CppGoogle = CPP_GOOGLE_INT, CppCatch2 = CPP_CATCH2_INT, @@ -182,6 +184,7 @@ impl Adapter { | Self::RustIai | Self::RustGungraun | Self::RustGungraunJson + | Self::RustGungraunStdout | Self::CppGoogle | Self::CppCatch2 | Self::GoBench @@ -210,6 +213,7 @@ impl fmt::Display for Adapter { Self::RustIai => write!(f, "rust_iai"), Self::RustGungraun => write!(f, "rust_gungraun"), Self::RustGungraunJson => write!(f, "rust_gungraun_json"), + Self::RustGungraunStdout => write!(f, "rust_gungraun_stdout"), Self::Cpp => write!(f, "cpp"), Self::CppGoogle => write!(f, "cpp_google"), Self::CppCatch2 => write!(f, "cpp_catch2"), @@ -243,8 +247,8 @@ mod adapter { DART_BENCHMARK_HARNESS_INT, DART_INT, GO_BENCH_INT, GO_INT, JAVA_INT, JAVA_JMH_INT, JS_BENCHMARK_INT, JS_INT, JS_TIME_INT, JS_VITEST_INT, JSON_INT, MAGIC_INT, PYTHON_ASV_INT, PYTHON_INT, PYTHON_PYTEST_INT, RUBY_BENCHMARK_INT, RUBY_INT, RUST_BENCH_INT, - RUST_CRITERION_INT, RUST_GUNGRAUN_INT, RUST_GUNGRAUN_JSON_INT, RUST_IAI_INT, RUST_INT, - SHELL_HYPERFINE_INT, SHELL_INT, + RUST_CRITERION_INT, RUST_GUNGRAUN_INT, RUST_GUNGRAUN_JSON_INT, RUST_GUNGRAUN_STDOUT_INT, + RUST_IAI_INT, RUST_INT, SHELL_HYPERFINE_INT, SHELL_INT, }; #[derive(Debug, thiserror::Error)] @@ -271,6 +275,7 @@ mod adapter { Self::RustIai => RUST_IAI_INT.to_sql(out), Self::RustGungraun => RUST_GUNGRAUN_INT.to_sql(out), Self::RustGungraunJson => RUST_GUNGRAUN_JSON_INT.to_sql(out), + Self::RustGungraunStdout => RUST_GUNGRAUN_STDOUT_INT.to_sql(out), Self::Cpp => CPP_INT.to_sql(out), Self::CppGoogle => CPP_GOOGLE_INT.to_sql(out), Self::CppCatch2 => CPP_CATCH2_INT.to_sql(out), @@ -312,6 +317,7 @@ mod adapter { RUST_IAI_INT => Ok(Self::RustIai), RUST_GUNGRAUN_INT => Ok(Self::RustGungraun), RUST_GUNGRAUN_JSON_INT => Ok(Self::RustGungraunJson), + RUST_GUNGRAUN_STDOUT_INT => Ok(Self::RustGungraunStdout), CPP_INT => Ok(Self::Cpp), CPP_GOOGLE_INT => Ok(Self::CppGoogle), CPP_CATCH2_INT => Ok(Self::CppCatch2), diff --git a/services/api/openapi.json b/services/api/openapi.json index 9c68bbd45..5957f1d45 100644 --- a/services/api/openapi.json +++ b/services/api/openapi.json @@ -11846,6 +11846,7 @@ "rust_iai", "rust_gungraun", "rust_gungraun_json", + "rust_gungraun_stdout", "cpp", "cpp_google", "cpp_catch2", diff --git a/services/console/src/types/bencher.ts b/services/console/src/types/bencher.ts index d638da2fd..d67af06f5 100644 --- a/services/console/src/types/bencher.ts +++ b/services/console/src/types/bencher.ts @@ -1048,6 +1048,7 @@ export enum Adapter { RustIai = "rust_iai", RustGungraun = "rust_gungraun", RustGungraunJson = "rust_gungraun_json", + RustGungraunStdout = "rust_gungraun_stdout", Cpp = "cpp", CppGoogle = "cpp_google", CppCatch2 = "cpp_catch2", From b834f4d9db4ee421f508c33749b9223a369fa5de Mon Sep 17 00:00:00 2001 From: gamma0987 Date: Tue, 11 Aug 2026 02:03:52 +0200 Subject: [PATCH 09/11] fix RustIaiCallgrind to RustGungraun, add new json, stdout adapters in the console --- .../components/adapter/BenchmarkHarnessFallback.tsx | 2 +- .../src/components/adapter/BenchmarkHarnessInner.tsx | 2 +- services/console/src/components/adapter/adapter.ts | 4 ++++ services/console/src/components/adapter/name.ts | 10 +++++++--- .../components/console/deck/hand/card/ViewCard.tsx | 12 ++++++++---- services/console/src/pages/rust/gungraun.astro | 2 +- 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/services/console/src/components/adapter/BenchmarkHarnessFallback.tsx b/services/console/src/components/adapter/BenchmarkHarnessFallback.tsx index e56387d20..d00093ebc 100644 --- a/services/console/src/components/adapter/BenchmarkHarnessFallback.tsx +++ b/services/console/src/components/adapter/BenchmarkHarnessFallback.tsx @@ -53,8 +53,8 @@ const BenchmarkHarnessFallback = () => ( adapters={[ Adapter.RustBench, Adapter.RustCriterion, + Adapter.RustGungraun, Adapter.RustIai, - Adapter.RustIaiCallgrind, ]} /> ( adapters={[ Adapter.RustBench, Adapter.RustCriterion, + Adapter.RustGungraun, Adapter.RustIai, - Adapter.RustIaiCallgrind, ]} /> { case Adapter.RustCriterion: case Adapter.RustIai: case Adapter.RustGungraun: + case Adapter.RustGungraunJson: + case Adapter.RustGungraunStdout: return RUST_ICON; case Adapter.CppGoogle: case Adapter.CppCatch2: @@ -63,6 +65,8 @@ export const adapterCommand = (isConsole: boolean, adapter: null | Adapter) => { case Adapter.RustCriterion: case Adapter.RustIai: case Adapter.RustGungraun: + case Adapter.RustGungraunJson: + case Adapter.RustGungraunStdout: return `bencher run${host} "cargo bench"`; case Adapter.CppGoogle: return `bencher run${host} "make benchmarks --benchmark_format=json"`; diff --git a/services/console/src/components/adapter/name.ts b/services/console/src/components/adapter/name.ts index 76bbeac6e..43448d968 100644 --- a/services/console/src/components/adapter/name.ts +++ b/services/console/src/components/adapter/name.ts @@ -12,8 +12,10 @@ export const adapterName = (adapter: Adapter): string => { return "Criterion"; case Adapter.RustIai: return "Iai"; - case Adapter.RustIaiCallgrind: - return "Iai-Callgrind"; + case Adapter.RustGungraun: + case Adapter.RustGungraunJson: + case Adapter.RustGungraunStdout: + return "Gungraun"; case Adapter.CppGoogle: return "Google Benchmark"; case Adapter.CppCatch2: @@ -51,7 +53,9 @@ export const adapterCommand = (isConsole: boolean, adapter: null | Adapter) => { return `bencher run${host} "cargo +nightly bench"`; case Adapter.RustCriterion: case Adapter.RustIai: - case Adapter.RustIaiCallgrind: + case Adapter.RustGungraun: + case Adapter.RustGungraunJson: + case Adapter.RustGungraunStdout: return `bencher run${host} "cargo bench"`; case Adapter.CppGoogle: return `bencher run${host} "make benchmarks --benchmark_format=json"`; diff --git a/services/console/src/components/console/deck/hand/card/ViewCard.tsx b/services/console/src/components/console/deck/hand/card/ViewCard.tsx index 21735b8c8..6b4ae72ad 100644 --- a/services/console/src/components/console/deck/hand/card/ViewCard.tsx +++ b/services/console/src/components/console/deck/hand/card/ViewCard.tsx @@ -462,8 +462,10 @@ const AdapterCard = (props: Props) => { return "-rust-criterion"; case Adapter.RustIai: return "-rust-iai"; - case Adapter.RustIaiCallgrind: - return "-rust-iai-callgrind"; + case Adapter.RustGungraun: + case Adapter.RustGungraunJson: + case Adapter.RustGungraunStdout: + return "-rust-gungraun"; case Adapter.ShellHyperfine: return "_%EF%B8%8F-shell-hyperfine"; default: @@ -511,8 +513,10 @@ const AdapterCard = (props: Props) => { return "Rust Criterion"; case Adapter.RustIai: return "Rust Iai"; - case Adapter.RustIaiCallgrind: - return "Rust Iai-Callgrind"; + case Adapter.RustGungraun: + case Adapter.RustGungraunJson: + case Adapter.RustGungraunStdout: + return "Rust Gungraun"; case Adapter.ShellHyperfine: return "Shell Hyperfine"; default: diff --git a/services/console/src/pages/rust/gungraun.astro b/services/console/src/pages/rust/gungraun.astro index d497f045a..d4a94dd61 100644 --- a/services/console/src/pages/rust/gungraun.astro +++ b/services/console/src/pages/rust/gungraun.astro @@ -46,7 +46,7 @@ import CallToAction from "../../components/landing/CallToAction.astro";
Learn More From a65851181fdfab2ab6ac994b5e7aa01090af026f Mon Sep 17 00:00:00 2001 From: gamma0987 Date: Wed, 12 Aug 2026 01:14:37 +0200 Subject: [PATCH 10/11] add gungraun pretty json parser --- lib/bencher_adapter/src/adapters/magic.rs | 18 +- .../src/adapters/rust/gungraun.rs | 18 +- .../src/adapters/rust/gungraun_json.rs | 181 +++++++++++++-- lib/bencher_adapter/src/adapters/rust/mod.rs | 8 + .../json_pretty_mixed_foreign_ndjson.txt | 123 ++++++++++ ...pretty_mixed_foreign_pretty_and_ndjson.txt | 128 ++++++++++ ...json_pretty_mixed_ndjson_two_callgrind.txt | 119 ++++++++++ .../gungraun/json_pretty_one_callgrind.txt | 114 +++++++++ .../json_pretty_one_callgrind_indented.txt | 116 ++++++++++ .../gungraun/json_pretty_two_callgrind.txt | 219 ++++++++++++++++++ 10 files changed, 1016 insertions(+), 28 deletions(-) create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_mixed_foreign_ndjson.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_mixed_foreign_pretty_and_ndjson.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_mixed_ndjson_two_callgrind.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_one_callgrind.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_one_callgrind_indented.txt create mode 100644 lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_two_callgrind.txt diff --git a/lib/bencher_adapter/src/adapters/magic.rs b/lib/bencher_adapter/src/adapters/magic.rs index b8f1821b7..d7a263b10 100644 --- a/lib/bencher_adapter/src/adapters/magic.rs +++ b/lib/bencher_adapter/src/adapters/magic.rs @@ -161,11 +161,21 @@ mod test_magic { #[test] fn adapter_magic_rust_gungraun_json() { - let results = convert_file_path::( - "./tool_output/rust/gungraun/json_one_callgrind_diff.txt", - ); + { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_pretty_one_callgrind.txt", + ); + + test_rust_gungraun_json::validate_adapter_rust_gungraun_json(&results); + } + + { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_callgrind_diff.txt", + ); - test_rust_gungraun_json::validate_adapter_rust_gungraun_json(&results); + test_rust_gungraun_json::validate_adapter_rust_gungraun_json(&results); + } } #[test] diff --git a/lib/bencher_adapter/src/adapters/rust/gungraun.rs b/lib/bencher_adapter/src/adapters/rust/gungraun.rs index 8701c64b5..5209980db 100644 --- a/lib/bencher_adapter/src/adapters/rust/gungraun.rs +++ b/lib/bencher_adapter/src/adapters/rust/gungraun.rs @@ -25,11 +25,21 @@ pub(crate) mod test_rust_gungraun { #[test] fn json() { - let results = convert_file_path::( - "./tool_output/rust/gungraun/json_one_callgrind_diff.txt", - ); + { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_one_callgrind_diff.txt", + ); + + validate_adapter_rust_gungraun_json(&results); + } + + { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_pretty_one_callgrind.txt", + ); - validate_adapter_rust_gungraun_json(&results); + validate_adapter_rust_gungraun_json(&results); + } } #[test] diff --git a/lib/bencher_adapter/src/adapters/rust/gungraun_json.rs b/lib/bencher_adapter/src/adapters/rust/gungraun_json.rs index 59f06d832..0ae80a2ee 100644 --- a/lib/bencher_adapter/src/adapters/rust/gungraun_json.rs +++ b/lib/bencher_adapter/src/adapters/rust/gungraun_json.rs @@ -4,10 +4,12 @@ use gungraun_summary::{ either_or_both::EitherOrBoth, util::SummaryByVersion, v6::{ - CachegrindMetric, DhatMetric, ErrorMetric, EventKind, Metric, MetricsDiff, MetricsSummary, - ToolMetricSummary, ValgrindTool, + BenchmarkSummary, CachegrindMetric, DhatMetric, ErrorMetric, EventKind, Metric, + MetricsDiff, MetricsSummary, ToolMetricSummary, ValgrindTool, }, }; +use std::fmt::Write as _; +use std::str::Lines; use crate::{Adaptable, AdapterResults, Settings, results::adapter_results::GungraunMeasure}; @@ -29,30 +31,53 @@ impl Adaptable for AdapterRustGungraunJson { } } +/// Parse json output in pretty and ndjson format +/// +/// Although it is currently not a possibility with gungraun cli/env options, this parser handles +/// mixed pretty and ndjson format making bencher future proof in that regard. The parser also +/// ignores intermixed json output from other tools or cargo itself, for example `cargo bench +/// --message-format=json`. fn parse_multiple(input: &str) -> Option)>> { - let parsed = input.lines().filter_map(parse_line).collect::>(); + let mut lines = input.lines(); + + let mut parsed = vec![]; + while let Some(line) = lines.next() { + let trimmed = line.trim(); + if trimmed == "{" { + let indent = line.len() - line.trim_start().len(); + if let Some(one) = parse_benchmark_pretty(&mut lines, indent) { + parsed.push(one); + } + } else if trimmed.starts_with('{') + && trimmed.ends_with('}') + && let Some(one) = parse_benchmark(line) + { + parsed.push(one); + } + } (!parsed.is_empty()).then_some(parsed) } -fn parse_line(input: &str) -> Option<(BenchmarkName, Vec)> { - // Using the version aware gungraun_summary parsing method to simplify adapting gungraun summary - // version updates. At the moment there's just v6 - let summary = match gungraun_summary::util::parse_slice(input.as_bytes()) { - Ok(summary_by_version) => match summary_by_version { - SummaryByVersion::V6(benchmark_summary) => benchmark_summary, - _ => return None, - }, - Err(_) => return None, - }; - - let name: BenchmarkName = if let Some(id) = &summary.id { - format!("{}::{id}", summary.module_path) - } else { - summary.module_path +fn parse_benchmark_pretty( + lines: &mut Lines<'_>, + indent: usize, +) -> Option<(BenchmarkName, Vec)> { + let mut payload = "{".to_owned(); + for line in lines { + writeln!(payload, "{line}").ok()?; + + let trimmed = line.trim(); + if trimmed == "}" && line.len() - line.trim_start().len() == indent { + break; + } } - .parse() - .ok()?; + + parse_benchmark(payload.as_str()) +} + +fn parse_benchmark(input: &str) -> Option<(BenchmarkName, Vec)> { + let (name, summary) = parse_json(input.as_bytes())?; let measures = summary .profiles @@ -85,6 +110,28 @@ fn parse_line(input: &str) -> Option<(BenchmarkName, Vec)> { Some((name, measures)) } +fn parse_json(input: &[u8]) -> Option<(BenchmarkName, BenchmarkSummary)> { + // Using the version aware gungraun_summary parsing method to simplify adapting gungraun summary + // version updates. At the moment there's just v6 + let summary = match gungraun_summary::util::parse_slice(input) { + Ok(summary_by_version) => match summary_by_version { + SummaryByVersion::V6(benchmark_summary) => benchmark_summary, + _ => return None, + }, + Err(_) => return None, + }; + + let name: BenchmarkName = if let Some(id) = &summary.id { + format!("{}::{id}", summary.module_path) + } else { + summary.module_path.clone() + } + .parse() + .ok()?; + + Some((name, summary)) +} + fn parse_drd_metrics_summary(metrics_summary: MetricsSummary) -> Vec { metrics_summary .0 @@ -603,6 +650,100 @@ pub(crate) mod test_rust_gungraun_json { } } + #[test] + fn pretty_one_callgrind() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_pretty_one_callgrind.txt", + ); + + validate_adapter_rust_gungraun_json(&results); + } + + #[test] + fn pretty_two_callgrind() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_pretty_two_callgrind.txt", + ); + + assert_eq!(results.inner.len(), 2); + + { + let expected = HashMap::from([(D1MissRate::SLUG_STR, 0.1), (D1mr::SLUG_STR, 6.0)]); + + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::first", + ); + } + + { + let expected = HashMap::from([(D1MissRate::SLUG_STR, 0.2), (D1mr::SLUG_STR, 7.0)]); + + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::second", + ); + } + } + + #[test] + fn pretty_mixed_ndjson_two_callgrind() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_pretty_mixed_ndjson_two_callgrind.txt", + ); + + assert_eq!(results.inner.len(), 2); + + { + let expected = HashMap::from([(D1MissRate::SLUG_STR, 0.1), (D1mr::SLUG_STR, 6.0)]); + + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::first", + ); + } + + { + let expected = HashMap::from([(D1MissRate::SLUG_STR, 0.2), (D1mr::SLUG_STR, 7.0)]); + + compare_benchmark( + &expected, + &results, + "play_game::bench_play_game_group::bench_play_game_100::second", + ); + } + } + + #[test] + fn pretty_mixed_with_foreign_ndjson() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_pretty_mixed_foreign_ndjson.txt", + ); + + validate_adapter_rust_gungraun_json(&results); + } + + #[test] + fn pretty_mixed_with_foreign_pretty_and_ndjson() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_pretty_mixed_foreign_pretty_and_ndjson.txt", + ); + + validate_adapter_rust_gungraun_json(&results); + } + + #[test] + fn pretty_one_callgrind_indented() { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_pretty_one_callgrind_indented.txt", + ); + + validate_adapter_rust_gungraun_json(&results); + } + pub fn validate_adapter_rust_gungraun_json(results: &AdapterResults) { let expected = HashMap::from([(D1MissRate::SLUG_STR, 0.1), (D1mr::SLUG_STR, 6.0)]); diff --git a/lib/bencher_adapter/src/adapters/rust/mod.rs b/lib/bencher_adapter/src/adapters/rust/mod.rs index 48c5ef21d..ed7e5410a 100644 --- a/lib/bencher_adapter/src/adapters/rust/mod.rs +++ b/lib/bencher_adapter/src/adapters/rust/mod.rs @@ -52,6 +52,14 @@ mod test_rust { #[test] fn adapter_rust_gungraun() { + { + let results = convert_file_path::( + "./tool_output/rust/gungraun/json_pretty_one_callgrind.txt", + ); + + test_rust_gungraun_json::validate_adapter_rust_gungraun_json(&results); + } + { let results = convert_file_path::( "./tool_output/rust/gungraun/json_one_callgrind_diff.txt", diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_mixed_foreign_ndjson.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_mixed_foreign_ndjson.txt new file mode 100644 index 000000000..a7c448cac --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_mixed_foreign_ndjson.txt @@ -0,0 +1,123 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +... some foreign json taken out from a real cargo bench --message-format=json run + +{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.12","manifest_path":"/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unicode-ident-1.0.12/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unicode_ident","src_path":"/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unicode-ident-1.0.12/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":false,"overflow_checks":false,"test":false},"features":[],"filenames":["/bencher/examples/rust/gungraun/target/release/deps/libunicode_ident-b9304a74ccd3330d.rlib","/bencher/examples/rust/gungraun/target/release/deps/libunicode_ident-b9304a74ccd3330d.rmeta"],"executable":null,"fresh":true} +{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/bencher/examples/rust/gungraun/target/release/build/serde_core-203a77995644e753/out"} +{"reason":"build-finished","success":true} + +{ + "baselines": [ + null, + null + ], + "benchmark_exe": "/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad", + "benchmark_file": "/bencher/examples/rust/gungraun/benches/play_game.rs", + "details": null, + "function_name": "bench_play_game_100", + "id": "some_id", + "kind": "LibraryBenchmark", + "module_path": "play_game::bench_play_game_group::bench_play_game_100", + "package_dir": "/bencher/examples/rust/gungraun", + "profiles": [ + { + "flamegraphs": [], + "log_paths": [ + "/callgrind.bench_play_game_100.log" + ], + "out_paths": [ + "/callgrind.bench_play_game_100.out" + ], + "summaries": { + "parts": [ + { + "details": { + "Left": { + "command": "/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000", + "details": null, + "parent_pid": null, + "part": 1, + "path": "/callgrind.bench_play_game_100.out", + "pid": 12345, + "thread": 1 + } + }, + "metrics_summary": { + "Callgrind": { + "D1MissRate": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Float": 0.1 + } + } + }, + "D1mr": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Int": 6 + } + } + } + } + } + } + ], + "total": { + "regressions": [], + "summary": { + "Callgrind": { + "D1MissRate": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Float": 0.1 + } + } + }, + "D1mr": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Int": 6 + } + } + } + } + } + } + }, + "tool": "Callgrind" + } + ], + "project_root": "/bencher/examples/rust/gungraun", + "summary_output": null, + "version": "6" +} + +and some json output after it + +{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.12","manifest_path":"/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unicode-ident-1.0.12/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unicode_ident","src_path":"/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unicode-ident-1.0.12/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":false,"overflow_checks":false,"test":false},"features":[],"filenames":["/bencher/examples/rust/gungraun/target/release/deps/libunicode_ident-b9304a74ccd3330d.rlib","/bencher/examples/rust/gungraun/target/release/deps/libunicode_ident-b9304a74ccd3330d.rmeta"],"executable":null,"fresh":true} +{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/bencher/examples/rust/gungraun/target/release/build/serde_core-203a77995644e753/out"} +{"reason":"build-finished","success":true} + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_mixed_foreign_pretty_and_ndjson.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_mixed_foreign_pretty_and_ndjson.txt new file mode 100644 index 000000000..c8db4a945 --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_mixed_foreign_pretty_and_ndjson.txt @@ -0,0 +1,128 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +... some foreign json taken out from a real cargo bench --message-format=json run + +{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.12","manifest_path":"/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unicode-ident-1.0.12/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unicode_ident","src_path":"/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unicode-ident-1.0.12/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":false,"overflow_checks":false,"test":false},"features":[],"filenames":["/bencher/examples/rust/gungraun/target/release/deps/libunicode_ident-b9304a74ccd3330d.rlib","/bencher/examples/rust/gungraun/target/release/deps/libunicode_ident-b9304a74ccd3330d.rmeta"],"executable":null,"fresh":true} + +... this is not original cargo bench output. we just need some foreign pretty json mixed with ndjson +{ + "reason": "build-script-executed", + "package_id": "registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228", + "linked_libs": [], + "linked_paths": [], + "cfgs": [], + "env": [], + "out_dir": "/bencher/examples/rust/gungraun/target/release/build/serde_core-203a77995644e753/out" +} + +{"reason":"build-finished","success":true} + +{ + "baselines": [ + null, + null + ], + "benchmark_exe": "/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad", + "benchmark_file": "/bencher/examples/rust/gungraun/benches/play_game.rs", + "details": null, + "function_name": "bench_play_game_100", + "id": "some_id", + "kind": "LibraryBenchmark", + "module_path": "play_game::bench_play_game_group::bench_play_game_100", + "package_dir": "/bencher/examples/rust/gungraun", + "profiles": [ + { + "flamegraphs": [], + "log_paths": [ + "/callgrind.bench_play_game_100.log" + ], + "out_paths": [ + "/callgrind.bench_play_game_100.out" + ], + "summaries": { + "parts": [ + { + "details": { + "Left": { + "command": "/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000", + "details": null, + "parent_pid": null, + "part": 1, + "path": "/callgrind.bench_play_game_100.out", + "pid": 12345, + "thread": 1 + } + }, + "metrics_summary": { + "Callgrind": { + "D1MissRate": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Float": 0.1 + } + } + }, + "D1mr": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Int": 6 + } + } + } + } + } + } + ], + "total": { + "regressions": [], + "summary": { + "Callgrind": { + "D1MissRate": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Float": 0.1 + } + } + }, + "D1mr": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Int": 6 + } + } + } + } + } + } + }, + "tool": "Callgrind" + } + ], + "project_root": "/bencher/examples/rust/gungraun", + "summary_output": null, + "version": "6" +} + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_mixed_ndjson_two_callgrind.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_mixed_ndjson_two_callgrind.txt new file mode 100644 index 000000000..d90a66fec --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_mixed_ndjson_two_callgrind.txt @@ -0,0 +1,119 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{ + "baselines": [ + null, + null + ], + "benchmark_exe": "/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad", + "benchmark_file": "/bencher/examples/rust/gungraun/benches/play_game.rs", + "details": null, + "function_name": "bench_play_game_100", + "id": "first", + "kind": "LibraryBenchmark", + "module_path": "play_game::bench_play_game_group::bench_play_game_100", + "package_dir": "/bencher/examples/rust/gungraun", + "profiles": [ + { + "flamegraphs": [], + "log_paths": [ + "/callgrind.bench_play_game_100.log" + ], + "out_paths": [ + "/callgrind.bench_play_game_100.out" + ], + "summaries": { + "parts": [ + { + "details": { + "Left": { + "command": "/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000", + "details": null, + "parent_pid": null, + "part": 1, + "path": "/callgrind.bench_play_game_100.out", + "pid": 12345, + "thread": 1 + } + }, + "metrics_summary": { + "Callgrind": { + "D1MissRate": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Float": 0.1 + } + } + }, + "D1mr": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Int": 6 + } + } + } + } + } + } + ], + "total": { + "regressions": [], + "summary": { + "Callgrind": { + "D1MissRate": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Float": 0.1 + } + } + }, + "D1mr": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Int": 6 + } + } + } + } + } + } + }, + "tool": "Callgrind" + } + ], + "project_root": "/bencher/examples/rust/gungraun", + "summary_output": null, + "version": "6" +} + +some text between... + + +{"baselines":[null,null],"benchmark_exe":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad","benchmark_file":"/bencher/examples/rust/gungraun/benches/play_game.rs","details":null,"function_name":"bench_play_game_100","id":"second","kind":"LibraryBenchmark","module_path":"play_game::bench_play_game_group::bench_play_game_100","package_dir":"/bencher/examples/rust/gungraun","profiles":[{"flamegraphs":[],"log_paths":["/callgrind.bench_play_game_100.log"],"out_paths":["/callgrind.bench_play_game_100.out"],"summaries":{"parts":[{"details":{"Left":{"command":"/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000","details":null,"parent_pid":null,"part":1,"path":"/callgrind.bench_play_game_100.out","pid":12345,"thread":1}},"metrics_summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Float":0.2}}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Int":7}}}}}}],"total":{"regressions":[],"summary":{"Callgrind":{"D1MissRate":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Float":0.2}}},"D1mr":{"diffs":{"diff_pct":"0","factor":"1"},"metrics":{"Left":{"Int":7}}}}}}},"tool":"Callgrind"}],"project_root":"/bencher/examples/rust/gungraun","summary_output":null,"version":"6"} + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_one_callgrind.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_one_callgrind.txt new file mode 100644 index 000000000..dbb47984c --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_one_callgrind.txt @@ -0,0 +1,114 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{ + "baselines": [ + null, + null + ], + "benchmark_exe": "/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad", + "benchmark_file": "/bencher/examples/rust/gungraun/benches/play_game.rs", + "details": null, + "function_name": "bench_play_game_100", + "id": "some_id", + "kind": "LibraryBenchmark", + "module_path": "play_game::bench_play_game_group::bench_play_game_100", + "package_dir": "/bencher/examples/rust/gungraun", + "profiles": [ + { + "flamegraphs": [], + "log_paths": [ + "/callgrind.bench_play_game_100.log" + ], + "out_paths": [ + "/callgrind.bench_play_game_100.out" + ], + "summaries": { + "parts": [ + { + "details": { + "Left": { + "command": "/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000", + "details": null, + "parent_pid": null, + "part": 1, + "path": "/callgrind.bench_play_game_100.out", + "pid": 12345, + "thread": 1 + } + }, + "metrics_summary": { + "Callgrind": { + "D1MissRate": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Float": 0.1 + } + } + }, + "D1mr": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Int": 6 + } + } + } + } + } + } + ], + "total": { + "regressions": [], + "summary": { + "Callgrind": { + "D1MissRate": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Float": 0.1 + } + } + }, + "D1mr": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Int": 6 + } + } + } + } + } + } + }, + "tool": "Callgrind" + } + ], + "project_root": "/bencher/examples/rust/gungraun", + "summary_output": null, + "version": "6" +} + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_one_callgrind_indented.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_one_callgrind_indented.txt new file mode 100644 index 000000000..0f18475d0 --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_one_callgrind_indented.txt @@ -0,0 +1,116 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +... with some indentation + + { + "baselines": [ + null, + null + ], + "benchmark_exe": "/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad", + "benchmark_file": "/bencher/examples/rust/gungraun/benches/play_game.rs", + "details": null, + "function_name": "bench_play_game_100", + "id": "some_id", + "kind": "LibraryBenchmark", + "module_path": "play_game::bench_play_game_group::bench_play_game_100", + "package_dir": "/bencher/examples/rust/gungraun", + "profiles": [ + { + "flamegraphs": [], + "log_paths": [ + "/callgrind.bench_play_game_100.log" + ], + "out_paths": [ + "/callgrind.bench_play_game_100.out" + ], + "summaries": { + "parts": [ + { + "details": { + "Left": { + "command": "/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000", + "details": null, + "parent_pid": null, + "part": 1, + "path": "/callgrind.bench_play_game_100.out", + "pid": 12345, + "thread": 1 + } + }, + "metrics_summary": { + "Callgrind": { + "D1MissRate": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Float": 0.1 + } + } + }, + "D1mr": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Int": 6 + } + } + } + } + } + } + ], + "total": { + "regressions": [], + "summary": { + "Callgrind": { + "D1MissRate": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Float": 0.1 + } + } + }, + "D1mr": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Int": 6 + } + } + } + } + } + } + }, + "tool": "Callgrind" + } + ], + "project_root": "/bencher/examples/rust/gungraun", + "summary_output": null, + "version": "6" + } + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... diff --git a/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_two_callgrind.txt b/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_two_callgrind.txt new file mode 100644 index 000000000..b75735130 --- /dev/null +++ b/lib/bencher_adapter/tool_output/rust/gungraun/json_pretty_two_callgrind.txt @@ -0,0 +1,219 @@ +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +{ + "baselines": [ + null, + null + ], + "benchmark_exe": "/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad", + "benchmark_file": "/bencher/examples/rust/gungraun/benches/play_game.rs", + "details": null, + "function_name": "bench_play_game_100", + "id": "first", + "kind": "LibraryBenchmark", + "module_path": "play_game::bench_play_game_group::bench_play_game_100", + "package_dir": "/bencher/examples/rust/gungraun", + "profiles": [ + { + "flamegraphs": [], + "log_paths": [ + "/callgrind.bench_play_game_100.log" + ], + "out_paths": [ + "/callgrind.bench_play_game_100.out" + ], + "summaries": { + "parts": [ + { + "details": { + "Left": { + "command": "/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000", + "details": null, + "parent_pid": null, + "part": 1, + "path": "/callgrind.bench_play_game_100.out", + "pid": 12345, + "thread": 1 + } + }, + "metrics_summary": { + "Callgrind": { + "D1MissRate": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Float": 0.1 + } + } + }, + "D1mr": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Int": 6 + } + } + } + } + } + } + ], + "total": { + "regressions": [], + "summary": { + "Callgrind": { + "D1MissRate": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Float": 0.1 + } + } + }, + "D1mr": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Int": 6 + } + } + } + } + } + } + }, + "tool": "Callgrind" + } + ], + "project_root": "/bencher/examples/rust/gungraun", + "summary_output": null, + "version": "6" +} + +some text between + + +{ + "baselines": [ + null, + null + ], + "benchmark_exe": "/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad", + "benchmark_file": "/bencher/examples/rust/gungraun/benches/play_game.rs", + "details": null, + "function_name": "bench_play_game_100", + "id": "second", + "kind": "LibraryBenchmark", + "module_path": "play_game::bench_play_game_group::bench_play_game_100", + "package_dir": "/bencher/examples/rust/gungraun", + "profiles": [ + { + "flamegraphs": [], + "log_paths": [ + "/callgrind.bench_play_game_100.log" + ], + "out_paths": [ + "/callgrind.bench_play_game_100.out" + ], + "summaries": { + "parts": [ + { + "details": { + "Left": { + "command": "/bencher/examples/rust/gungraun/target/release/deps/play_game-4a31ce0553c3b8ad --gungraun-run 00000 00000 00000", + "details": null, + "parent_pid": null, + "part": 1, + "path": "/callgrind.bench_play_game_100.out", + "pid": 12345, + "thread": 1 + } + }, + "metrics_summary": { + "Callgrind": { + "D1MissRate": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Float": 0.2 + } + } + }, + "D1mr": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Int": 7 + } + } + } + } + } + } + ], + "total": { + "regressions": [], + "summary": { + "Callgrind": { + "D1MissRate": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Float": 0.2 + } + } + }, + "D1mr": { + "diffs": { + "diff_pct": "0", + "factor": "1" + }, + "metrics": { + "Left": { + "Int": 7 + } + } + } + } + } + } + }, + "tool": "Callgrind" + } + ], + "project_root": "/bencher/examples/rust/gungraun", + "summary_output": null, + "version": "6" +} + + + +.... Some trailing text that should be ignored ... + + +.... Some trailing text that should be ignored ... +.... Some trailing text that should be ignored ... From ce66214f2e0662294ce69445a02ce15e064223f8 Mon Sep 17 00:00:00 2001 From: gamma0987 Date: Wed, 12 Aug 2026 01:39:48 +0200 Subject: [PATCH 11/11] apply review and sort gungraun stdout before json --- lib/bencher_adapter/src/lib.rs | 2 +- lib/bencher_json/src/project/report.rs | 14 +++++++------- services/api/openapi.json | 2 +- services/console/src/components/adapter/adapter.ts | 4 ++-- services/console/src/components/adapter/name.ts | 4 ++-- .../components/console/deck/hand/card/ViewCard.tsx | 4 ++-- services/console/src/types/bencher.ts | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/bencher_adapter/src/lib.rs b/lib/bencher_adapter/src/lib.rs index 3fa538be8..44e542f5f 100644 --- a/lib/bencher_adapter/src/lib.rs +++ b/lib/bencher_adapter/src/lib.rs @@ -68,8 +68,8 @@ impl Adaptable for Adapter { Adapter::RustCriterion => AdapterRustCriterion::parse(input, settings), Adapter::RustIai => AdapterRustIai::parse(input, settings), Adapter::RustGungraun => AdapterRustGungraun::parse(input, settings), - Adapter::RustGungraunJson => AdapterRustGungraunJson::parse(input, settings), Adapter::RustGungraunStdout => AdapterRustGungraunStdout::parse(input, settings), + Adapter::RustGungraunJson => AdapterRustGungraunJson::parse(input, settings), Adapter::Shell => AdapterShell::parse(input, settings), Adapter::ShellHyperfine => AdapterShellHyperfine::parse(input, settings), } diff --git a/lib/bencher_json/src/project/report.rs b/lib/bencher_json/src/project/report.rs index 014ea2361..33bee299e 100644 --- a/lib/bencher_json/src/project/report.rs +++ b/lib/bencher_json/src/project/report.rs @@ -90,8 +90,8 @@ const RUST_BENCH_INT: i32 = 21; const RUST_CRITERION_INT: i32 = 22; const RUST_IAI_INT: i32 = 23; const RUST_GUNGRAUN_INT: i32 = 24; -const RUST_GUNGRAUN_JSON_INT: i32 = 25; -const RUST_GUNGRAUN_STDOUT_INT: i32 = 26; +const RUST_GUNGRAUN_STDOUT_INT: i32 = 25; +const RUST_GUNGRAUN_JSON_INT: i32 = 26; const CPP_INT: i32 = 30; const CPP_GOOGLE_INT: i32 = 31; const CPP_CATCH2_INT: i32 = 32; @@ -134,8 +134,8 @@ pub enum Adapter { // https://github.com/bencherdev/bencher/issues/619 #[serde(alias = "rust_iai_callgrind")] RustGungraun = RUST_GUNGRAUN_INT, - RustGungraunJson = RUST_GUNGRAUN_JSON_INT, RustGungraunStdout = RUST_GUNGRAUN_STDOUT_INT, + RustGungraunJson = RUST_GUNGRAUN_JSON_INT, Cpp = CPP_INT, CppGoogle = CPP_GOOGLE_INT, CppCatch2 = CPP_CATCH2_INT, @@ -183,8 +183,8 @@ impl Adapter { | Self::RustCriterion | Self::RustIai | Self::RustGungraun - | Self::RustGungraunJson | Self::RustGungraunStdout + | Self::RustGungraunJson | Self::CppGoogle | Self::CppCatch2 | Self::GoBench @@ -212,8 +212,8 @@ impl fmt::Display for Adapter { Self::RustCriterion => write!(f, "rust_criterion"), Self::RustIai => write!(f, "rust_iai"), Self::RustGungraun => write!(f, "rust_gungraun"), - Self::RustGungraunJson => write!(f, "rust_gungraun_json"), Self::RustGungraunStdout => write!(f, "rust_gungraun_stdout"), + Self::RustGungraunJson => write!(f, "rust_gungraun_json"), Self::Cpp => write!(f, "cpp"), Self::CppGoogle => write!(f, "cpp_google"), Self::CppCatch2 => write!(f, "cpp_catch2"), @@ -274,8 +274,8 @@ mod adapter { Self::RustCriterion => RUST_CRITERION_INT.to_sql(out), Self::RustIai => RUST_IAI_INT.to_sql(out), Self::RustGungraun => RUST_GUNGRAUN_INT.to_sql(out), - Self::RustGungraunJson => RUST_GUNGRAUN_JSON_INT.to_sql(out), Self::RustGungraunStdout => RUST_GUNGRAUN_STDOUT_INT.to_sql(out), + Self::RustGungraunJson => RUST_GUNGRAUN_JSON_INT.to_sql(out), Self::Cpp => CPP_INT.to_sql(out), Self::CppGoogle => CPP_GOOGLE_INT.to_sql(out), Self::CppCatch2 => CPP_CATCH2_INT.to_sql(out), @@ -316,8 +316,8 @@ mod adapter { RUST_CRITERION_INT => Ok(Self::RustCriterion), RUST_IAI_INT => Ok(Self::RustIai), RUST_GUNGRAUN_INT => Ok(Self::RustGungraun), - RUST_GUNGRAUN_JSON_INT => Ok(Self::RustGungraunJson), RUST_GUNGRAUN_STDOUT_INT => Ok(Self::RustGungraunStdout), + RUST_GUNGRAUN_JSON_INT => Ok(Self::RustGungraunJson), CPP_INT => Ok(Self::Cpp), CPP_GOOGLE_INT => Ok(Self::CppGoogle), CPP_CATCH2_INT => Ok(Self::CppCatch2), diff --git a/services/api/openapi.json b/services/api/openapi.json index 5957f1d45..e08ac4d3c 100644 --- a/services/api/openapi.json +++ b/services/api/openapi.json @@ -11845,8 +11845,8 @@ "rust_criterion", "rust_iai", "rust_gungraun", - "rust_gungraun_json", "rust_gungraun_stdout", + "rust_gungraun_json", "cpp", "cpp_google", "cpp_catch2", diff --git a/services/console/src/components/adapter/adapter.ts b/services/console/src/components/adapter/adapter.ts index 2a1994d76..8c08b0705 100644 --- a/services/console/src/components/adapter/adapter.ts +++ b/services/console/src/components/adapter/adapter.ts @@ -25,8 +25,8 @@ export const adapterIcon = (adapter: Adapter) => { case Adapter.RustCriterion: case Adapter.RustIai: case Adapter.RustGungraun: - case Adapter.RustGungraunJson: case Adapter.RustGungraunStdout: + case Adapter.RustGungraunJson: return RUST_ICON; case Adapter.CppGoogle: case Adapter.CppCatch2: @@ -65,8 +65,8 @@ export const adapterCommand = (isConsole: boolean, adapter: null | Adapter) => { case Adapter.RustCriterion: case Adapter.RustIai: case Adapter.RustGungraun: - case Adapter.RustGungraunJson: case Adapter.RustGungraunStdout: + case Adapter.RustGungraunJson: return `bencher run${host} "cargo bench"`; case Adapter.CppGoogle: return `bencher run${host} "make benchmarks --benchmark_format=json"`; diff --git a/services/console/src/components/adapter/name.ts b/services/console/src/components/adapter/name.ts index 43448d968..0facd7f4e 100644 --- a/services/console/src/components/adapter/name.ts +++ b/services/console/src/components/adapter/name.ts @@ -13,8 +13,8 @@ export const adapterName = (adapter: Adapter): string => { case Adapter.RustIai: return "Iai"; case Adapter.RustGungraun: - case Adapter.RustGungraunJson: case Adapter.RustGungraunStdout: + case Adapter.RustGungraunJson: return "Gungraun"; case Adapter.CppGoogle: return "Google Benchmark"; @@ -54,8 +54,8 @@ export const adapterCommand = (isConsole: boolean, adapter: null | Adapter) => { case Adapter.RustCriterion: case Adapter.RustIai: case Adapter.RustGungraun: - case Adapter.RustGungraunJson: case Adapter.RustGungraunStdout: + case Adapter.RustGungraunJson: return `bencher run${host} "cargo bench"`; case Adapter.CppGoogle: return `bencher run${host} "make benchmarks --benchmark_format=json"`; diff --git a/services/console/src/components/console/deck/hand/card/ViewCard.tsx b/services/console/src/components/console/deck/hand/card/ViewCard.tsx index 6b4ae72ad..7532a443d 100644 --- a/services/console/src/components/console/deck/hand/card/ViewCard.tsx +++ b/services/console/src/components/console/deck/hand/card/ViewCard.tsx @@ -463,8 +463,8 @@ const AdapterCard = (props: Props) => { case Adapter.RustIai: return "-rust-iai"; case Adapter.RustGungraun: - case Adapter.RustGungraunJson: case Adapter.RustGungraunStdout: + case Adapter.RustGungraunJson: return "-rust-gungraun"; case Adapter.ShellHyperfine: return "_%EF%B8%8F-shell-hyperfine"; @@ -514,8 +514,8 @@ const AdapterCard = (props: Props) => { case Adapter.RustIai: return "Rust Iai"; case Adapter.RustGungraun: - case Adapter.RustGungraunJson: case Adapter.RustGungraunStdout: + case Adapter.RustGungraunJson: return "Rust Gungraun"; case Adapter.ShellHyperfine: return "Shell Hyperfine"; diff --git a/services/console/src/types/bencher.ts b/services/console/src/types/bencher.ts index d67af06f5..b51cc5223 100644 --- a/services/console/src/types/bencher.ts +++ b/services/console/src/types/bencher.ts @@ -1047,8 +1047,8 @@ export enum Adapter { RustCriterion = "rust_criterion", RustIai = "rust_iai", RustGungraun = "rust_gungraun", - RustGungraunJson = "rust_gungraun_json", RustGungraunStdout = "rust_gungraun_stdout", + RustGungraunJson = "rust_gungraun_json", Cpp = "cpp", CppGoogle = "cpp_google", CppCatch2 = "cpp_catch2",