library(ggplot2) library(dplyr) library(readr) library(stringr) # Usage: Rscript combined_fault_rates.r exp_abspath1 exp_abspath2 ... [faults_file] args <- commandArgs(trailingOnly = TRUE) if (length(args) < 1) { stop("Need at least 1 experiment") } csv_suffix <- if (grepl("\\.csv$", args[length(args)])) { args[length(args)] } else { "faults.csv" } exp_args <- if (grepl("\\.csv$", args[length(args)])) { args[-length(args)] } else { args } # Faults / instruction count, per experiment rates <- data.frame() for (arg in exp_args) { faults_file <- file.path(arg, csv_suffix) mnem_file <- file.path(arg, "mnemonics.csv") if (!file.exists(faults_file)) { warning(paste("Missing:", faults_file)) next } if (!file.exists(mnem_file)) { warning(paste("Missing:", mnem_file)) next } df <- read_csv(faults_file, col_types = cols()) mdf <- read_csv(mnem_file, col_types = cols()) total_faults <- df |> filter(resulttype != "OK_MARKER") |> summarise(faults = sum(faults, na.rm = TRUE)) |> pull(faults) total_instrs <- sum(mdf$count, na.rm = TRUE) if (is.na(total_instrs) || total_instrs == 0) { warning(paste("Zero instruction count for", arg)) next } match <- str_match( basename(arg), "^\\d{2}-\\d{2}_\\d{2}-\\d{2}-\\d{2}_(.+?)_(c|aot|interp)_" ) if (is.na(match[1, 1])) { base_name <- basename(arg) variant <- "unknown" } else { base_name <- match[1, 2] variant <- match[1, 3] } rates <- bind_rows( rates, data.frame( base_name = base_name, variant = variant, fault_rate = total_faults / total_instrs ) ) } if (nrow(rates) == 0) { stop("No data loaded") } # Order base_names by their max fault rate base_order <- rates |> group_by(base_name) |> summarise(max_rate = max(fault_rate), .groups = "drop") |> arrange(desc(max_rate)) |> pull(base_name) rates <- rates |> mutate( base_name = factor(base_name, levels = base_order), variant = factor(variant, levels = c("c", "aot", "interp", "unknown")) ) plot <- ggplot( rates, aes(x = base_name, y = fault_rate, fill = variant) ) + geom_col(position = position_dodge(preserve = "single")) + scale_y_log10() + labs( title = "Fault Rate per Instruction", x = "Experiment", y = "Faults / Instruction Count", fill = "Variant" ) + theme_minimal() + theme( axis.text.x = element_text(angle = 90, hjust = 1), plot.title = element_text(size = 14, face = "bold") ) suffix <- gsub("^faults|\\.csv$", "", csv_suffix) outfile <- paste0("injections/fault_rates_per_instruction", suffix, ".svg") ggsave(outfile, plot = plot, width = 12, height = 6) print(paste("Saved", outfile))