Add alternative resultsdata query that reconstructs fspgroup table instead of depending on it
This commit is contained in:
@@ -0,0 +1,55 @@
|
|||||||
|
package ResultsDataWriteGroups;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use diagnostics;
|
||||||
|
|
||||||
|
use FindBin;
|
||||||
|
use lib "$FindBin::Bin/../Modules";
|
||||||
|
use Filters;
|
||||||
|
|
||||||
|
use feature 'say';
|
||||||
|
|
||||||
|
sub query {
|
||||||
|
my ( $experiment, $experiment_dir, @filter_config_names ) = @_;
|
||||||
|
|
||||||
|
my $extra =
|
||||||
|
Filters::build_filter_clause( $experiment_dir, @filter_config_names );
|
||||||
|
|
||||||
|
# This query asks the same question as ResultsData.pm: How much faultspace
|
||||||
|
# area ended up in each possible outcome?
|
||||||
|
#
|
||||||
|
# The difference is how the write equivalence classes are treated.
|
||||||
|
# BasicPruner's write-group INSERT maps every 'W' trace entry to the single
|
||||||
|
# known_outcome=1 write pilot, but fspgroup has PRIMARY KEY (pilot_id), so
|
||||||
|
# only the first row lands in the table.
|
||||||
|
# This query fixes that.
|
||||||
|
my $querystring = "SELECT
|
||||||
|
benchmark, resulttype, SUM(t.time2 - t.time1 + 1) AS faults
|
||||||
|
FROM variant v
|
||||||
|
JOIN trace t ON v.id = t.variant_id
|
||||||
|
JOIN fsppilot p ON p.variant_id = t.variant_id
|
||||||
|
AND ( (p.known_outcome = 1 AND t.accesstype = 'W')
|
||||||
|
OR (p.known_outcome = 0 AND p.instr2 = t.instr2 AND p.data_physical_address = t.data_physical_address) )
|
||||||
|
JOIN result_GenericExperimentMessage r ON r.pilot_id = p.id
|
||||||
|
WHERE v.variant = '$experiment'$extra
|
||||||
|
GROUP BY v.id, resulttype
|
||||||
|
ORDER BY variant, benchmark, resulttype;";
|
||||||
|
|
||||||
|
say $querystring;
|
||||||
|
|
||||||
|
return $querystring;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub args { return "--batch --raw"; }
|
||||||
|
|
||||||
|
sub filename {
|
||||||
|
my @filter_config_names = grep { defined && length } @_;
|
||||||
|
my $suffix =
|
||||||
|
@filter_config_names ? "_" . join( "+", sort @filter_config_names ) : "";
|
||||||
|
return "resultsdata_writegroups${suffix}.csv";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub postprocess { $_[0] =~ s/\t/,/g; }
|
||||||
|
|
||||||
|
1;
|
||||||
+133
-130
@@ -100,6 +100,9 @@ my %handlers = (
|
|||||||
ResultsDataPruned =>
|
ResultsDataPruned =>
|
||||||
'Faults summary per benchmark with resulttype, using the pruned data without expansion (resultsdata_pruned.csv)',
|
'Faults summary per benchmark with resulttype, using the pruned data without expansion (resultsdata_pruned.csv)',
|
||||||
|
|
||||||
|
ResultsDataWriteGroups =>
|
||||||
|
'Faults summary per benchmark with resulttype, with write equivalence classes reconstructed from fsppilot (resultsdata_writegroups.csv)',
|
||||||
|
|
||||||
TargetClass =>
|
TargetClass =>
|
||||||
'Faults by code type with data type (stack/heap/bss/...) and resulttype -> targetclass.csv',
|
'Faults by code type with data type (stack/heap/bss/...) and resulttype -> targetclass.csv',
|
||||||
|
|
||||||
@@ -832,7 +835,7 @@ my %handlers = (
|
|||||||
|
|
||||||
'32. Import Database (Mars)' => sub {
|
'32. Import Database (Mars)' => sub {
|
||||||
|
|
||||||
# Import databse dump on mars
|
# Import database dump on mars
|
||||||
die "No dumps in $local_dump_dir" unless -d $local_dump_dir;
|
die "No dumps in $local_dump_dir" unless -d $local_dump_dir;
|
||||||
my @dumps = grep { /\.sql$/ } Util::find_files($local_dump_dir);
|
my @dumps = grep { /\.sql$/ } Util::find_files($local_dump_dir);
|
||||||
my @selected_dumps =
|
my @selected_dumps =
|
||||||
@@ -861,135 +864,135 @@ my %handlers = (
|
|||||||
'<', Util::shell_quote($dump_file) );
|
'<', Util::shell_quote($dump_file) );
|
||||||
},
|
},
|
||||||
|
|
||||||
'33. Repair fspgroup Write Groups (Mars)' => sub {
|
# '33. Repair fspgroup Write Groups (Mars)' => sub {
|
||||||
|
#
|
||||||
# Retroactively fixes (hopefully) the missing equivalence class
|
# # Retroactively fixes (hopefully) the missing equivalence class
|
||||||
# mappings (EC <-> Pilot) the BasicPruner misses (because it maps
|
# # mappings (EC <-> Pilot) the BasicPruner misses (because it maps
|
||||||
# multiple classes to a single pilot, but uses the pilot as the
|
# # multiple classes to a single pilot, but uses the pilot as the
|
||||||
# primary key)
|
# # primary key)
|
||||||
my @dbs = Mars::db_list();
|
# my @dbs = Mars::db_list();
|
||||||
my @dbs_with_notes;
|
# my @dbs_with_notes;
|
||||||
foreach my $db (@dbs) {
|
# foreach my $db (@dbs) {
|
||||||
my $info =
|
# my $info =
|
||||||
Util::read_experiment_info( $db =~ s/smchurla_//r =~ s/:/-/gr );
|
# Util::read_experiment_info( $db =~ s/smchurla_//r =~ s/:/-/gr );
|
||||||
|
#
|
||||||
push @dbs_with_notes,
|
# push @dbs_with_notes,
|
||||||
( defined $info && length($info) > 0 )
|
# ( defined $info && length($info) > 0 )
|
||||||
? sprintf( "%-60s (%s)", $db, $info )
|
# ? sprintf( "%-60s (%s)", $db, $info )
|
||||||
: $db;
|
# : $db;
|
||||||
}
|
# }
|
||||||
|
#
|
||||||
my @selected_dbs = TUI::select_from_list( "Select Databases to Repair",
|
# my @selected_dbs = TUI::select_from_list( "Select Databases to Repair",
|
||||||
1, @dbs_with_notes );
|
# 1, @dbs_with_notes );
|
||||||
die "No database selected" unless @selected_dbs;
|
# die "No database selected" unless @selected_dbs;
|
||||||
|
#
|
||||||
@selected_dbs =
|
# @selected_dbs =
|
||||||
map { s/(.*?)\s+\(.+\)$/$1/r } @selected_dbs;
|
# map { s/(.*?)\s+\(.+\)$/$1/r } @selected_dbs;
|
||||||
|
#
|
||||||
# The PRIMARY KEY gets dropped by the repair and replaced with a KEY.
|
# # The PRIMARY KEY gets dropped by the repair and replaced with a KEY.
|
||||||
# To not run this shit on already repaired DBs, check for the PRIMARY
|
# # To not run this shit on already repaired DBs, check for the PRIMARY
|
||||||
# index as a determinant
|
# # index as a determinant
|
||||||
my $index_exists = sub {
|
# my $index_exists = sub {
|
||||||
my ($index) = @_;
|
# my ($index) = @_;
|
||||||
my ($count) = Mars::db_selectrow(
|
# my ($count) = Mars::db_selectrow(
|
||||||
"SELECT COUNT(*) FROM information_schema.STATISTICS
|
# "SELECT COUNT(*) FROM information_schema.STATISTICS
|
||||||
WHERE TABLE_SCHEMA = DATABASE()
|
# WHERE TABLE_SCHEMA = DATABASE()
|
||||||
AND TABLE_NAME = 'fspgroup'
|
# AND TABLE_NAME = 'fspgroup'
|
||||||
AND INDEX_NAME = '$index'"
|
# AND INDEX_NAME = '$index'"
|
||||||
);
|
# );
|
||||||
return $count;
|
# return $count;
|
||||||
};
|
# };
|
||||||
|
#
|
||||||
foreach my $db (@selected_dbs) {
|
# foreach my $db (@selected_dbs) {
|
||||||
say "Repairing $db...";
|
# say "Repairing $db...";
|
||||||
|
#
|
||||||
# Select the DB so index_exists works
|
# # Select the DB so index_exists works
|
||||||
Mars::db_do("use `$db`");
|
# Mars::db_do("use `$db`");
|
||||||
|
#
|
||||||
# Update the variant names, so the queries still work
|
# # Update the variant names, so the queries still work
|
||||||
my $expected_variant = $db =~ s/^smchurla_//r;
|
# my $expected_variant = $db =~ s/^smchurla_//r;
|
||||||
my ($variant_count) =
|
# my ($variant_count) =
|
||||||
Mars::db_selectrow("SELECT COUNT(DISTINCT variant) FROM variant");
|
# Mars::db_selectrow("SELECT COUNT(DISTINCT variant) FROM variant");
|
||||||
my ($current_variant) =
|
# my ($current_variant) =
|
||||||
Mars::db_selectrow("SELECT DISTINCT variant FROM variant");
|
# Mars::db_selectrow("SELECT DISTINCT variant FROM variant");
|
||||||
|
#
|
||||||
if ( !defined $variant_count || $variant_count != 1 ) {
|
# if ( !defined $variant_count || $variant_count != 1 ) {
|
||||||
say " - WARNING: $variant_count distinct variants!";
|
# say " - WARNING: $variant_count distinct variants!";
|
||||||
}
|
# }
|
||||||
elsif ( $current_variant ne $expected_variant ) {
|
# elsif ( $current_variant ne $expected_variant ) {
|
||||||
say " - Variant is '$current_variant' but queries look up"
|
# say " - Variant is '$current_variant' but queries look up"
|
||||||
. " '$expected_variant' (from the database name), renaming...";
|
# . " '$expected_variant' (from the database name), renaming...";
|
||||||
Mars::db_do("UPDATE variant SET variant = '$expected_variant'");
|
# Mars::db_do("UPDATE variant SET variant = '$expected_variant'");
|
||||||
}
|
# }
|
||||||
|
#
|
||||||
# Drop the primary key
|
# # Drop the primary key
|
||||||
if ( $index_exists->('PRIMARY') ) {
|
# if ( $index_exists->('PRIMARY') ) {
|
||||||
say " - Dropping PRIMARY KEY (pilot_id)...";
|
# say " - Dropping PRIMARY KEY (pilot_id)...";
|
||||||
Mars::db_do("ALTER TABLE fspgroup DROP PRIMARY KEY");
|
# Mars::db_do("ALTER TABLE fspgroup DROP PRIMARY KEY");
|
||||||
}
|
# }
|
||||||
|
#
|
||||||
# Add an index for the columns we actually join on (mostly)
|
# # Add an index for the columns we actually join on (mostly)
|
||||||
unless ( $index_exists->('eq_class') ) {
|
# unless ( $index_exists->('eq_class') ) {
|
||||||
say " - Adding eq_class index...";
|
# say " - Adding eq_class index...";
|
||||||
Mars::db_do(
|
# Mars::db_do(
|
||||||
"ALTER TABLE fspgroup
|
# "ALTER TABLE fspgroup
|
||||||
ADD KEY eq_class (variant_id, instr2, data_physical_address)"
|
# ADD KEY eq_class (variant_id, instr2, data_physical_address)"
|
||||||
);
|
# );
|
||||||
}
|
# }
|
||||||
|
#
|
||||||
# I'm currently only using BasicPruner, but don't touch other
|
# # I'm currently only using BasicPruner, but don't touch other
|
||||||
# pruning methods for now, for safety
|
# # pruning methods for now, for safety
|
||||||
my ($fspmethod_id) =
|
# my ($fspmethod_id) =
|
||||||
Mars::db_selectrow(
|
# Mars::db_selectrow(
|
||||||
"SELECT id FROM fspmethod WHERE method = 'basic'");
|
# "SELECT id FROM fspmethod WHERE method = 'basic'");
|
||||||
die "No 'basic' fspmethod in $db" unless defined $fspmethod_id;
|
# die "No 'basic' fspmethod in $db" unless defined $fspmethod_id;
|
||||||
|
#
|
||||||
# The first row succeeded before the duplicate key error, remove it
|
# # The first row succeeded before the duplicate key error, remove it
|
||||||
Mars::db_do(
|
# Mars::db_do(
|
||||||
"DELETE g
|
# "DELETE g
|
||||||
FROM fspgroup g
|
# FROM fspgroup g
|
||||||
JOIN fsppilot p ON p.id = g.pilot_id
|
# JOIN fsppilot p ON p.id = g.pilot_id
|
||||||
WHERE p.known_outcome = 1 AND p.fspmethod_id = $fspmethod_id"
|
# WHERE p.known_outcome = 1 AND p.fspmethod_id = $fspmethod_id"
|
||||||
);
|
# );
|
||||||
|
#
|
||||||
my ($expected) =
|
# my ($expected) =
|
||||||
Mars::db_selectrow(
|
# Mars::db_selectrow(
|
||||||
"SELECT COUNT(*) FROM trace WHERE accesstype = 'W'");
|
# "SELECT COUNT(*) FROM trace WHERE accesstype = 'W'");
|
||||||
|
#
|
||||||
# Query from BasicPruner.cc, now ran against the updated DB
|
# # Query from BasicPruner.cc, now ran against the updated DB
|
||||||
say " - Inserting $expected write groups...";
|
# say " - Inserting $expected write groups...";
|
||||||
Mars::db_do(
|
# Mars::db_do(
|
||||||
"INSERT INTO
|
# "INSERT INTO
|
||||||
fspgroup (variant_id, instr2, data_physical_address, bit_pos, fspmethod_id, pilot_id)
|
# fspgroup (variant_id, instr2, data_physical_address, bit_pos, fspmethod_id, pilot_id)
|
||||||
SELECT STRAIGHT_JOIN t.variant_id, t.instr2, t.data_physical_address, p.bit_pos, p.fspmethod_id, p.id
|
# SELECT STRAIGHT_JOIN t.variant_id, t.instr2, t.data_physical_address, p.bit_pos, p.fspmethod_id, p.id
|
||||||
FROM fsppilot p
|
# FROM fsppilot p
|
||||||
JOIN trace t
|
# JOIN trace t
|
||||||
ON t.variant_id = p.variant_id AND p.fspmethod_id = $fspmethod_id AND p.known_outcome = 1
|
# ON t.variant_id = p.variant_id AND p.fspmethod_id = $fspmethod_id AND p.known_outcome = 1
|
||||||
WHERE t.accesstype = 'W'"
|
# WHERE t.accesstype = 'W'"
|
||||||
);
|
# );
|
||||||
|
#
|
||||||
# We expect one row per write group/EC.
|
# # We expect one row per write group/EC.
|
||||||
# Otherwise no idea what's going on :O
|
# # Otherwise no idea what's going on :O
|
||||||
my ($actual) = Mars::db_selectrow(
|
# my ($actual) = Mars::db_selectrow(
|
||||||
"SELECT COUNT(*)
|
# "SELECT COUNT(*)
|
||||||
FROM fspgroup g
|
# FROM fspgroup g
|
||||||
JOIN fsppilot p ON p.id = g.pilot_id
|
# JOIN fsppilot p ON p.id = g.pilot_id
|
||||||
WHERE p.known_outcome = 1 AND p.fspmethod_id = $fspmethod_id"
|
# WHERE p.known_outcome = 1 AND p.fspmethod_id = $fspmethod_id"
|
||||||
);
|
# );
|
||||||
|
#
|
||||||
if ( $actual == $expected ) {
|
# if ( $actual == $expected ) {
|
||||||
say " - OK: $actual write groups match the write ECs in trace";
|
# say " - OK: $actual write groups match the write ECs in trace";
|
||||||
}
|
# }
|
||||||
else {
|
# else {
|
||||||
say " - WARNING: inserted $actual, expected $expected."
|
# say " - WARNING: inserted $actual, expected $expected."
|
||||||
. " Check for duplicate known_outcome pilots:"
|
# . " Check for duplicate known_outcome pilots:"
|
||||||
. " SELECT variant_id, COUNT(*) FROM fsppilot"
|
# . " SELECT variant_id, COUNT(*) FROM fsppilot"
|
||||||
. " WHERE known_outcome = 1 GROUP BY variant_id;";
|
# . " WHERE known_outcome = 1 GROUP BY variant_id;";
|
||||||
}
|
# }
|
||||||
}
|
# }
|
||||||
|
#
|
||||||
say "Queries have to be re-run.";
|
# say "Queries have to be re-run.";
|
||||||
},
|
# },
|
||||||
|
|
||||||
'95. Delete Builds' => sub {
|
'95. Delete Builds' => sub {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user