diff options
| author | leochanj105 <leochanj@live.unc.edu> | 2020-10-23 02:12:49 -0400 |
|---|---|---|
| committer | leochanj105 <leochanj@live.unc.edu> | 2020-10-23 02:12:49 -0400 |
| commit | e23e931be4776b89149fdb2596f47096e6cdb78c (patch) | |
| tree | faf3963cc501f103cd2554553ec74ce21157b42e /smt_analysis | |
| parent | e2d933df44b7b387b41c8c7805393ad3857c4448 (diff) | |
| parent | e0217a963c6c0e0667d41d075038685956bcfacf (diff) | |
Merge branch 'sd-vbs' of ssh://rtsrv.cs.unc.edu/public/mc2-scripts-and-benchmarks into sd-vbs
Diffstat (limited to 'smt_analysis')
| -rwxr-xr-x | smt_analysis/computeLCslowdown.py | 73 | ||||
| -rwxr-xr-x | smt_analysis/computeSMTslowdown.py | 155 | ||||
| -rwxr-xr-x | smt_analysis/libSMT.py | 151 | ||||
| m--------- | smt_analysis/plotille | 0 |
4 files changed, 379 insertions, 0 deletions
diff --git a/smt_analysis/computeLCslowdown.py b/smt_analysis/computeLCslowdown.py new file mode 100755 index 0000000..bcd22da --- /dev/null +++ b/smt_analysis/computeLCslowdown.py | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | #!/usr/bin/python3 | ||
| 2 | import numpy as np | ||
| 3 | import sys | ||
| 4 | import plotille.plotille as plt | ||
| 5 | from libSMT import * | ||
| 6 | TIMING_ERROR = 1000 #ns | ||
| 7 | ASYNC_FORMAT = False | ||
| 8 | |||
| 9 | def print_usage(): | ||
| 10 | print("This program takes in the all-pairs and baseline SMT data and computes the worst-case slowdown against any other task when SMT is enabled.", file=sys.stderr) | ||
| 11 | print("Level-A/B usage: {} <file -A> <file -B> <baseline file>".format(sys.argv[0]), file=sys.stderr) | ||
| 12 | print("Level-C usage: {} <continuous pairs> <baseline file>".format(sys.argv[0]), file=sys.stderr) | ||
| 13 | |||
| 14 | # Check that we got the right number of parameters | ||
| 15 | if len(sys.argv) < 3: | ||
| 16 | print_usage() | ||
| 17 | exit() | ||
| 18 | |||
| 19 | if len(sys.argv) > 3: | ||
| 20 | print("Reading file using synchronous pair format...") | ||
| 21 | print("Are you sure you want to do this? For the RTAS'21 paper, L-A/-B pairs should use the other script.") | ||
| 22 | input("Press enter to continue, Ctrl+C to exit...") | ||
| 23 | else: | ||
| 24 | print("Reading file using asynchronous pair format...") | ||
| 25 | ASYNC_FORMAT = True | ||
| 26 | |||
| 27 | assert_valid_input_files(sys.argv[1:-1], print_usage) | ||
| 28 | |||
| 29 | # Pull in the data | ||
| 30 | if not ASYNC_FORMAT: | ||
| 31 | baseline_times, baseline_sample_cnt, baseline_max_times = load_baseline(sys.argv[3]) | ||
| 32 | paired_times, paired_offsets, name_to_idx, idx_to_name = load_paired(sys.argv[1], sys.argv[2], len(list(baseline_times.keys()))) | ||
| 33 | for key in baseline_times: | ||
| 34 | print(key,max(baseline_times[key])) | ||
| 35 | else: | ||
| 36 | baseline_times, baseline_sample_cnt, baseline_max_times = load_baseline(sys.argv[2]) | ||
| 37 | paired_times, name_to_idx, idx_to_name = load_fake_paired(sys.argv[1]) | ||
| 38 | |||
| 39 | # We work iff the baseline was run for the same set of benchmarks as the pairs were | ||
| 40 | assert_base_and_pair_keys_match(baseline_times, name_to_idx) | ||
| 41 | |||
| 42 | # Only consider benchmarks that are at least an order of magnitude longer than the timing error | ||
| 43 | reliableNames = [] | ||
| 44 | for i in range(0, len(name_to_idx)): | ||
| 45 | benchmark = idx_to_name[i] | ||
| 46 | if min(baseline_times[benchmark]) > TIMING_ERROR * 10: | ||
| 47 | reliableNames.append(benchmark) | ||
| 48 | |||
| 49 | # Compute worst-case SMT slowdown for each benchmark | ||
| 50 | print("Bench Mi") | ||
| 51 | # Print rows | ||
| 52 | sample_f = np.mean # Change this to np.mean to use mean values in Mi generation | ||
| 53 | M_vals = [] | ||
| 54 | for b1 in reliableNames: | ||
| 55 | print("{:<14.14}:".format(b1), end=" ") | ||
| 56 | max_mi = 0 | ||
| 57 | # Scan through everyone we ran against and find our maximum slowdown | ||
| 58 | for b2 in reliableNames: | ||
| 59 | time_with_smt = sample_f(paired_times[name_to_idx[b1]][name_to_idx[b2]]) | ||
| 60 | time_wout_smt = sample_f(baseline_times[b1]) | ||
| 61 | M = time_with_smt / time_wout_smt | ||
| 62 | max_mi = max(max_mi, M) | ||
| 63 | print("{:>10.3}".format(max_mi), end=" ") | ||
| 64 | M_vals.append(max_mi) | ||
| 65 | print("") | ||
| 66 | # Print some statistics about the distribution | ||
| 67 | print("Average: {:>5.3} with standard deviation {:>5.3} using `{}`".format(np.mean(M_vals), np.std(M_vals), sample_f.__name__)) | ||
| 68 | Ms = np.asarray(M_vals, dtype=np.float32) | ||
| 69 | print(np.sum(Ms <= 1), "of", len(M_vals), "M_i values are at most one -", 100*np.sum(Ms <= 1)/len(M_vals), "percent") | ||
| 70 | print(np.sum(Ms > 2), "of", len(M_vals), "M_i values are greater than two -", 100*np.sum(Ms > 2)/len(M_vals), "percent") | ||
| 71 | M_vals_to_plot = Ms | ||
| 72 | |||
| 73 | print(plt.hist(M_vals_to_plot, bins=10)) | ||
diff --git a/smt_analysis/computeSMTslowdown.py b/smt_analysis/computeSMTslowdown.py new file mode 100755 index 0000000..805def1 --- /dev/null +++ b/smt_analysis/computeSMTslowdown.py | |||
| @@ -0,0 +1,155 @@ | |||
| 1 | #!/usr/bin/python3 | ||
| 2 | from typing import List, Any | ||
| 3 | import numpy as np | ||
| 4 | from scipy import stats | ||
| 5 | import sys | ||
| 6 | import plotille.plotille as plt | ||
| 7 | TIMING_ERROR = 1000 #ns | ||
| 8 | LEVEL_C_ANALYSIS = False | ||
| 9 | from libSMT import * | ||
| 10 | |||
| 11 | def print_usage(): | ||
| 12 | print("This program takes in the all-pairs and baseline SMT data and computes how much each program is slowed when SMT in enabled.", file=sys.stderr) | ||
| 13 | print("Level-A/B usage: {} <file -A> <file -B> <baseline file> --cij".format(sys.argv[0]), file=sys.stderr) | ||
| 14 | print("Level-C usage: {} <continuous pairs> <baseline file>".format(sys.argv[0]), file=sys.stderr) | ||
| 15 | |||
| 16 | # Check that we got the right number of parameters | ||
| 17 | if len(sys.argv) < 3: | ||
| 18 | print_usage() | ||
| 19 | exit() | ||
| 20 | |||
| 21 | if len(sys.argv) > 3: | ||
| 22 | print("Analyzing results using Level-A/B methodology...") | ||
| 23 | else: | ||
| 24 | print("Analyzing results using Level-C methodology...") | ||
| 25 | LEVEL_C_ANALYSIS = True | ||
| 26 | |||
| 27 | assert_valid_input_files(sys.argv[1:-1], print_usage); | ||
| 28 | |||
| 29 | # Print Cij values rather than Mij | ||
| 30 | TIMES_ONLY = len(sys.argv) > 4 and "--cij" in sys.argv[4] | ||
| 31 | OK_PAIRS_ONLY = len(sys.argv) > 4 and "--cij-ok" in sys.argv[4] | ||
| 32 | |||
| 33 | # Pull in the data | ||
| 34 | if not LEVEL_C_ANALYSIS: | ||
| 35 | baseline_times, baseline_sample_cnt, baseline_max_times = load_baseline(sys.argv[3]) | ||
| 36 | paired_times, paired_offsets, name_to_idx, idx_to_name = load_paired(sys.argv[1], sys.argv[2], len(list(baseline_times.keys()))) | ||
| 37 | for key in baseline_times: | ||
| 38 | print(key,max(baseline_times[key])) | ||
| 39 | else: | ||
| 40 | # Paired times use an abuse of the baseline file format | ||
| 41 | baseline_times, baseline_sample_cnt, baseline_max_times = load_baseline(sys.argv[2]) | ||
| 42 | paired_times, name_to_idx, idx_to_name = load_fake_paired(sys.argv[1]) | ||
| 43 | |||
| 44 | # We work iff the baseline was run for the same set of benchmarks as the pairs were | ||
| 45 | assert_base_and_pair_keys_match(baseline_times, name_to_idx) | ||
| 46 | |||
| 47 | # Only consider benchmarks that are at least an order of magnitude longer than the timing error | ||
| 48 | reliableNames = [] | ||
| 49 | for i in range(0, len(name_to_idx)): | ||
| 50 | benchmark = idx_to_name[i] | ||
| 51 | if min(baseline_times[benchmark]) > TIMING_ERROR * 10: | ||
| 52 | reliableNames.append(benchmark) | ||
| 53 | |||
| 54 | # Compute SMT slowdown for each benchmark | ||
| 55 | # Output format: table, each row is one benchmark and each column is one benchmark | ||
| 56 | # each cell is base1 + base2*m = pair solved for m, aka (pair - base1) / base2 | ||
| 57 | # Print table header | ||
| 58 | print("Bench ", end=" ") | ||
| 59 | for name in reliableNames: | ||
| 60 | if not TIMES_ONLY: print("{:<10.10}".format(name), end=" ") | ||
| 61 | if TIMES_ONLY: print("{:<12.12}".format(name), end=" ") | ||
| 62 | print() | ||
| 63 | # Print rows | ||
| 64 | sample_f = max # Change this to np.mean to use mean values in Mij generation | ||
| 65 | M_vals = [] | ||
| 66 | for b1 in reliableNames: | ||
| 67 | if not TIMES_ONLY: print("{:<14.14}:".format(b1), end=" ") | ||
| 68 | if TIMES_ONLY: print("{:<14.14}:".format(b1), end=" ") | ||
| 69 | for b2 in reliableNames: | ||
| 70 | if not LEVEL_C_ANALYSIS: | ||
| 71 | Ci = max(sample_f(baseline_times[b1]), sample_f(baseline_times[b2])) | ||
| 72 | Cj = min(sample_f(baseline_times[b1]), sample_f(baseline_times[b2])) | ||
| 73 | Cij = sample_f(paired_times[name_to_idx[b1]][name_to_idx[b2]]) | ||
| 74 | if False: | ||
| 75 | M = np.std(paired_times[name_to_idx[b1]][name_to_idx[b2]]) / np.mean(paired_times[name_to_idx[b1]][name_to_idx[b2]]) | ||
| 76 | else: | ||
| 77 | M = (Cij - Ci) / Cj | ||
| 78 | if Cij and Cj * 10 > Ci: # We don't pair tasks with more than a 10x difference in length | ||
| 79 | M_vals.append(M) | ||
| 80 | if not TIMES_ONLY: print("{:>10.3}".format(M), end=" ") | ||
| 81 | else: | ||
| 82 | if not TIMES_ONLY: print("{:>10}".format("N/A"), end=" ") | ||
| 83 | |||
| 84 | if TIMES_ONLY and (not OK_PAIRS_ONLY or Cj * 10 > Ci): | ||
| 85 | print("{:>12}".format(Cij), end=" ") | ||
| 86 | elif OK_PAIRS_ONLY and Cj * 10 <= Ci: | ||
| 87 | print("{:>12}".format("0"), end=" ") | ||
| 88 | |||
| 89 | else: | ||
| 90 | time_with_smt = sample_f(paired_times[name_to_idx[b1]][name_to_idx[b2]]) | ||
| 91 | time_wout_smt = sample_f(baseline_times[b1]) | ||
| 92 | M = time_with_smt / time_wout_smt | ||
| 93 | M_vals.append(M) | ||
| 94 | print("{:>10.3}".format(M), end=" ") | ||
| 95 | print("") | ||
| 96 | # Print some statistics about the distribution | ||
| 97 | print("Average: {:>5.3} with standard deviation {:>5.3} using `{}`".format(np.mean(M_vals), np.std(M_vals), sample_f.__name__)) | ||
| 98 | Ms = np.asarray(M_vals, dtype=np.float32) | ||
| 99 | if not LEVEL_C_ANALYSIS: | ||
| 100 | print(np.sum(Ms <= 0), "of", len(M_vals), "M_i:j values are at most zero -", 100*np.sum(Ms <= 0)/len(M_vals), "percent") | ||
| 101 | print(np.sum(Ms > 1), "of", len(M_vals), "M_i:j values are greater than one -", 100*np.sum(Ms > 1)/len(M_vals), "percent") | ||
| 102 | M_vals_to_plot = Ms[np.logical_and(Ms > 0, Ms <= 1)] | ||
| 103 | else: | ||
| 104 | print(np.sum(Ms <= 1), "of", len(M_vals), "M_i:j values are at most one -", 100*np.sum(Ms <= 1)/len(M_vals), "percent") | ||
| 105 | print(np.sum(Ms > 2), "of", len(M_vals), "M_i:j values are greater than two -", 100*np.sum(Ms > 2)/len(M_vals), "percent") | ||
| 106 | M_vals_to_plot = Ms | ||
| 107 | |||
| 108 | print("Using Sim's analysis, average: {:>5.3} with standard deviation {:>5.3} using `{}`".format(np.mean(list(M_vals_to_plot)), np.std(list(M_vals_to_plot)), sample_f.__name__)) | ||
| 109 | print(plt.hist(M_vals_to_plot, bins=10)) | ||
| 110 | |||
