From 6c7351b3d1e247291a170f27495f1db40b932e6a Mon Sep 17 00:00:00 2001 From: Christoph Urlacher Date: Wed, 22 Apr 2026 15:40:57 +0200 Subject: [PATCH] add result comparison menu action --- scripts/Util.pm | 2 + scripts/menu.pl | 150 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 120 insertions(+), 32 deletions(-) diff --git a/scripts/Util.pm b/scripts/Util.pm index 2a37d86..108c372 100644 --- a/scripts/Util.pm +++ b/scripts/Util.pm @@ -118,6 +118,8 @@ sub execute_query { my $argsstring = $args->(); my $filenamestring = $filename->(); + # TODO: Pass the values instead of rewriting db.conf. + # Can also use DBI's database handle directly. my $result = qx{mariadb --defaults-file=$db_conf $argsstring -e "$querystring"}; die "Query failed: $?" if $? != 0; diff --git a/scripts/menu.pl b/scripts/menu.pl index 76ea9fd..fbc5907 100644 --- a/scripts/menu.pl +++ b/scripts/menu.pl @@ -10,6 +10,7 @@ use lib $FindBin::Bin; use Util; use Mars; use TUI; +use Text::CSV_XS; use feature 'say'; @@ -246,44 +247,92 @@ my %handlers = ( "--port=$resultbrowser_port" ); }, - '14. Run Build in GDB' => sub { - my @builds = grep { /linux/ } Util::find_subdirs($local_builds_dir); - my @selected_builds = - TUI::select_from_list( "Select Build to Run in GDB", 0, @builds ); - die "No experiment selected" unless @selected_builds; - my $selected_build = $selected_builds[0]; + '14. Compare Experiment Results' => sub { - my $build_dir = "$local_builds_dir/$selected_build"; - my $build_name = $selected_build =~ s/.*-.*-.*:.*:.*?_(.*)-.*-.*/$1/r; - my $module_source = "$local_root/build-$build_name"; + # TODO: To util function (select_experiments, + # could also include the file-existance filter) + my @experiments = Util::find_subdirs($local_archive_dir); - say "$build_name"; + # Only include experiments with resultsdata.csv + my @viable_experiments; + foreach my $experiment (@experiments) { + push @viable_experiments, $experiment + if ( -f "$local_archive_dir/$experiment/resultsdata.csv" ); + } - system( - 'gdb', - '--tui', - '-q', - "$build_dir/system.elf", - '-ex', - "set substitute-path '$module_source' '$build_dir'", - '-ex', - "set substitute-path '/build/source/core' '$local_wamr/core'", - '-ex', - 'break main', - '-ex', - 'break fail_start_trace', - '-ex', - 'break fail_stop_trace', - '-ex', - 'break fail_marker_positive', - '-ex', - 'break fail_marker_detected', - '-ex', - 'break fail_marker_negative', + # Select experiments + my @selected_experiments = + TUI::select_from_list( "Select Experiments to Compare", + 1, @viable_experiments ); + die "No experiments selected" unless @selected_experiments; + + # Read results + my %all_results; + foreach my $experiment (@selected_experiments) { + + # Schema: benchmark, resulttype, faults + my $data = Text::CSV_XS::csv( + in => "$local_archive_dir/$experiment/resultsdata.csv", + headers => 'auto' + ); + + foreach my $row (@$data) { + $all_results{$experiment}{ $row->{benchmark} } + { $row->{resulttype} } = $row->{faults}; + } + } + + # TODO: To util function + sub format_number_sep { + my ($number) = @_; + 1 while $number =~ s/^(-?\d+)(\d{3})/$1.$2/; + return $number; + } + + my @benchs = ( 'ip', 'mem', 'regs' ); + my @markers = ( + 'OK_MARKER', 'FAIL_MARKER', + 'DETECTED_MARKER', 'TIMEOUT', + 'TRAP', 'WRITE_TEXTSEGMENT', + 'ACCESS_OUTERSPACE' ); + + my $heading = sprintf( "%5s %20s ", "BENCH", "TYPE" ); + foreach my $experiment (@selected_experiments) { + $heading .= sprintf( "%50s ", $experiment ); + } + + my @entries = ( $heading, "" ); + foreach my $benchmark (@benchs) { + foreach my $marker (@markers) { + my $entry = sprintf( "%5s %20s ", $benchmark, $marker ); + + foreach my $experiment (@selected_experiments) { + if ( exists $all_results{$experiment}{$benchmark}{$marker} ) + { + $entry .= sprintf( + "%50s ", + format_number_sep( + $all_results{$experiment}{$benchmark}{$marker} + ) + ); + } + else { + $entry .= sprintf( "%50s ", "" ); + } + } + + push @entries, $entry; + } + push @entries, ""; + } + + TUI::select_from_list( + "Comparing " . scalar(@selected_experiments) . " Experiments", + 0, @entries ); }, - '20. Plot Results' => sub { + '15. Plot Results' => sub { # Generate R ggplot2 charts my @experiments = Util::find_subdirs($local_archive_dir); @@ -320,6 +369,43 @@ my %handlers = ( } }, + '16. Run Build in GDB' => sub { + my @builds = grep { /linux/ } Util::find_subdirs($local_builds_dir); + my @selected_builds = + TUI::select_from_list( "Select Build to Run in GDB", 0, @builds ); + die "No experiment selected" unless @selected_builds; + my $selected_build = $selected_builds[0]; + + my $build_dir = "$local_builds_dir/$selected_build"; + my $build_name = $selected_build =~ s/.*-.*-.*:.*:.*?_(.*)-.*-.*/$1/r; + my $module_source = "$local_root/build-$build_name"; + + say "$build_name"; + + system( + 'gdb', + '--tui', + '-q', + "$build_dir/system.elf", + '-ex', + "set substitute-path '$module_source' '$build_dir'", + '-ex', + "set substitute-path '/build/source/core' '$local_wamr/core'", + '-ex', + 'break main', + '-ex', + 'break fail_start_trace', + '-ex', + 'break fail_stop_trace', + '-ex', + 'break fail_marker_positive', + '-ex', + 'break fail_marker_detected', + '-ex', + 'break fail_marker_negative', + ); + }, + '95. Delete Builds' => sub { # Delete old build files