diff options
-rwxr-xr-x | fossil_replay.sh | 12 | ||||
-rwxr-xr-x | si-report.py | 83 |
2 files changed, 61 insertions, 34 deletions
diff --git a/fossil_replay.sh b/fossil_replay.sh index 4731254..282de81 100755 --- a/fossil_replay.sh +++ b/fossil_replay.sh @@ -32,17 +32,25 @@ for db in `find -L "$1" -type f -name "*.foz"`; do fi # Append stdout/stderr to file to reduce spam - echo "Replaying $db" + echo -n "Replaying $db" echo "Replaying $db" >> "/tmp/fossil_replay.txt" rm -f "$2".tmp + + start_time_ns=$(date +%s%N) fossilize-replay --enable-pipeline-stats "$2".tmp ${@:3} "$db" 1>&2 2>> "/tmp/fossil_replay.txt" + end_time_ns=$(date +%s%N) # Check for failures if [ ! -e "$2".tmp ]; then rm -f "$2".tmp.__tmp.foz - echo "Replay of $db failed" + echo " failed" grep "pipeline crashed or hung" /tmp/fossil_replay.txt exit 1 + else + duration_ns=$(($end_time_ns-$start_time_ns)) + duration_s=$(($duration_ns/1000000000)) + duration_cs=$(($(($duration_ns/10000000))-$(($duration_s*100)))) + echo " took $duration_s.$(($duration_cs))s" fi # Append to result CSV diff --git a/si-report.py b/si-report.py index 2172ca8..5fb9373 100755 --- a/si-report.py +++ b/si-report.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4: */ # # Copyright 2015 Advanced Micro Devices, Inc. @@ -89,16 +89,21 @@ def cmp_min_per(current, comp): class si_stats: metrics = [ - ('sgprs', 'SGPRS', ''), - ('vgprs', 'VGPRS', ''), - ('spilled_sgprs', 'Spilled SGPRs', ''), - ('spilled_vgprs', 'Spilled VGPRs', ''), - ('privmem_vgprs', 'Private memory VGPRs', ''), - ('scratch_size', 'Scratch size', 'dwords per thread'), - ('code_size', 'Code Size', 'bytes'), - ('maxwaves', 'Max Waves', ''), - ('outputs', 'Outputs', ''), - ('patchoutputs', 'Patch Outputs', ''), + # variable, full name, table name, units + ('sgprs', 'SGPRs', 'SGPRs', ''), + ('vgprs', 'VGPRs', 'VGPRs', ''), + ('spilled_sgprs', 'Spilled SGPRs', 'SpillSGPR', ''), + ('spilled_vgprs', 'Spilled VGPRs', 'SpillVGPR', ''), + ('privmem_vgprs', 'Private memory VGPRs', 'PrivVGPR', ''), + ('scratch_size', 'Scratch size', 'Scratch', 'dwords per thread'), + ('code_size', 'Code Size', 'CodeSize', 'bytes'), + ('maxwaves', 'Max Waves', 'MaxWaves', ''), + ('ls_outputs', 'LS Outputs', 'LSOutputs', ''), + ('hs_outputs', 'HS Outputs', 'HSOutputs', ''), + ('hs_patch_outputs', 'HS Patch Outputs', 'PatchOuts', ''), + ('es_outputs', 'ES Outputs', 'ESOutputs', ''), + ('gs_outputs', 'GS Outputs', 'GSOutputs', ''), + ('vs_outputs', 'VS Outputs', 'VSOutputs', ''), ] def __init__(self): @@ -122,7 +127,7 @@ class si_stats: def to_string(self, suffixes=True): strings = [] - for name, printname, suffix in si_stats.metrics: + for name, printname, _, suffix in si_stats.metrics: string = " {}: {}".format(printname, get_str(self.__dict__[name])) if suffixes and len(suffix) > 0: @@ -195,6 +200,12 @@ class si_parser(object): re.compile( r"^Shader Stats: SGPRS: ([0-9]+) VGPRS: ([0-9]+) Code Size: ([0-9]+) " + r"LDS: ([0-9]+) Scratch: ([0-9]+) Max Waves: ([0-9]+) Spilled SGPRs: " + + r"([0-9]+) Spilled VGPRs: ([0-9]+) PrivMem VGPRs: ([0-9]+) LSOutputs: ([0-9]+) " + + r"HSOutputs: ([0-9]+) HSPatchOuts: ([0-9]+) ESOutputs: ([0-9]+) GSOutputs: ([0-9]+) " + + r"VSOutputs: ([0-9]+)"), + re.compile( + r"^Shader Stats: SGPRS: ([0-9]+) VGPRS: ([0-9]+) Code Size: ([0-9]+) " + + r"LDS: ([0-9]+) Scratch: ([0-9]+) Max Waves: ([0-9]+) Spilled SGPRs: " + r"([0-9]+) Spilled VGPRs: ([0-9]+) PrivMem VGPRs: ([0-9]+) Outputs: ([0-9]+) " + r"PatchOutputs: ([0-9]+)"), re.compile( @@ -233,13 +244,17 @@ class si_parser(object): self._stats.sgprs = int(match.group(1)) self._stats.vgprs = int(match.group(2)) self._stats.code_size = int(match.group(3)) - self._stats.scratch_size = int(match.group(5)) / (64 * 4) + self._stats.scratch_size = int(int(match.group(5)) / 64 / 4) self._stats.maxwaves = int(match.group(6)) self._stats.spilled_sgprs = int(match.group(7)) self._stats.spilled_vgprs = int(match.group(8)) self._stats.privmem_vgprs = int(match.group(9)) if match.lastindex >= 9 else 0 - self._stats.outputs = int(match.group(10)) if match.lastindex >= 10 else 0 - self._stats.patchoutputs = int(match.group(11)) if match.lastindex >= 11 else 0 + self._stats.ls_outputs = int(match.group(10)) if match.lastindex >= 17 else 0 + self._stats.hs_outputs = int(match.group(11)) if match.lastindex >= 17 else 0 + self._stats.hs_patch_outputs = int(match.group(12)) if match.lastindex >= 17 else 0 + self._stats.es_outputs = int(match.group(13)) if match.lastindex >= 17 else 0 + self._stats.gs_outputs = int(match.group(14)) if match.lastindex >= 17 else 0 + self._stats.vs_outputs = int(match.group(15)) if match.lastindex >= 17 else 0 old_stats = self._stats self._stats = None return old_stats @@ -323,16 +338,16 @@ def divide_stats(num, div): return result -def print_before_after_stats(before, after, divisor=1): +def print_before_after_stats(before, after): result = si_stats() for name in result.get_metrics(): - b = before.__dict__[name] / divisor - a = after.__dict__[name] / divisor + b = before.__dict__[name] + a = after.__dict__[name] if b == 0: percent = format_float(0.0) else: percent = format_float(100 * float(a - b) / float(b)) - result.__dict__[name] = '{} -> {} ({})'.format(get_str(b, ''), get_str(a, ''), percent) + result.__dict__[name] = '{} -> {} ({})'.format(b, a, percent) print(result) @@ -485,7 +500,7 @@ class grouped_stats: if not is_different(self.before, self.after): return - print("| {:{app_width}} |{:{shader_width}}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|".format( + print(("| {:{app_width}} |{:{shader_width}}|" + "{}|" * len(si_stats.metrics)).format( name, self.num_shaders, format_percent_change(self.before.sgprs, self.after.sgprs, min_width=len(legend[1])), @@ -496,8 +511,12 @@ class grouped_stats: format_percent_change(self.before.scratch_size, self.after.scratch_size, min_width=len(legend[6])), format_percent_change(self.before.code_size, self.after.code_size, min_width=len(legend[7])), format_percent_change(self.before.maxwaves, self.after.maxwaves, min_width=len(legend[8]), more_is_better=True), - format_percent_change(self.before.outputs, self.after.outputs, min_width=len(legend[9])), - format_percent_change(self.before.patchoutputs, self.after.patchoutputs, min_width=len(legend[10])), + format_percent_change(self.before.ls_outputs, self.after.ls_outputs, min_width=len(legend[9])), + format_percent_change(self.before.hs_outputs, self.after.hs_outputs, min_width=len(legend[10])), + format_percent_change(self.before.hs_patch_outputs, self.after.hs_patch_outputs, min_width=len(legend[11])), + format_percent_change(self.before.es_outputs, self.after.es_outputs, min_width=len(legend[12])), + format_percent_change(self.before.gs_outputs, self.after.gs_outputs, min_width=len(legend[13])), + format_percent_change(self.before.vs_outputs, self.after.vs_outputs, min_width=len(legend[14])), app_width=align, shader_width=len(legend[0]))) @@ -592,13 +611,13 @@ def print_tables(before_all_results, after_all_results): if num == 24: break if num > 0: - print + print("") # VGPR spilling apps print_yellow("VGPR SPILLING APPS\nShaders SpillVGPR PrivVGPR ScratchSize") for name, stats in sorted(apps.items()): stats.print_vgpr_spilling_app(name) - print + print("") # worst SGPR spills num = 0 @@ -612,13 +631,13 @@ def print_tables(before_all_results, after_all_results): if num == 24: break if num > 0: - print + print("") # SGPR spilling apps print_yellow(" SGPR SPILLING APPS\nShaders SpillSGPR AvgPerSh") for name, stats in sorted(apps.items()): stats.print_sgpr_spilling_app(name) - print + print("") # worst regressions metrics = si_stats().metrics @@ -648,7 +667,7 @@ def print_tables(before_all_results, after_all_results): if num == 24: break if num > 0: - print + print("") # biggest improvements metrics = si_stats().metrics @@ -678,22 +697,22 @@ def print_tables(before_all_results, after_all_results): if num == 24: break if num > 0: - print + print("") # percentages - longest_app_name = max(longest_app_name, len("AFFECTED APPS")) + longest_app_name = max(longest_app_name, len("Affected shaders")) title = "| {:^{width}} |".format("AFFECTED APPS", width=longest_app_name) - legend = ["{:^9}".format(s) for s in ["Shaders", "SGPRs", "VGPRs", "SpillSGPR", "SpillVGPR", "PrivVGPR", "Scratch", "CodeSize", "MaxWaves", "Outputs", "PatchOuts"]] + legend = ["{:^9}".format(s) for s in ["Shaders"] + [m[2] for m in metrics]] header = title + "|".join(legend) + "|" print_yellow(header) print("|".join(["-" * len(a) for a in (header).split("|")])) for name, stats in sorted(apps.items()): stats.print_percentages_end(name, longest_app_name, legend) print("|".join(["-" * len(a) for a in (header).split("|")])) - total_affected.print_percentages_end("All affected shaders", longest_app_name, legend) + total_affected.print_percentages_end("Affected shaders", longest_app_name, legend) print("|".join(["-" * len(a) for a in (header).split("|")])) total.print_percentages_end("Total", longest_app_name, legend) - print + print("") def main(): |