diff options
author | Marek Olšák <marek.olsak@amd.com> | 2025-07-08 06:43:57 -0400 |
---|---|---|
committer | Marek Olšák <marek.olsak@amd.com> | 2025-07-10 06:37:43 -0400 |
commit | 080ccd9af7142a3878d12ed6c406580e4aba33ad (patch) | |
tree | e2593d965a601b311ade00effd4ce2e68ada6acb | |
parent | d17b405c6e85ad9b3e1ca2acb6aea16e7223b884 (diff) |
si-report.py: improve output
-rwxr-xr-x | si-report.py | 89 |
1 files changed, 36 insertions, 53 deletions
diff --git a/si-report.py b/si-report.py index 9761739..192c39d 100755 --- a/si-report.py +++ b/si-report.py @@ -58,7 +58,9 @@ def format_table_cell(n, more_is_better=False, colored=True, is_percent=False): if abs(n) < 0.01: return "{:>{width}}".format(". ", width=min_width) - if n <= -100 or n >= 1000: + if n >= 10000: + str = "{:>{width}.0f}%".format(n, width=min_width - 1) + elif n <= -100 or n >= 1000: str = "{:>{width}.1f}%".format(n, width=min_width - 1) else: str = "{:>{width}.2f}%".format(n, width=min_width - 1) @@ -97,6 +99,7 @@ def cmp_min_per(current, comp): class si_stats: metrics = [ # variable, full name, table name, units + ('shader_type', 'Shader Type', 'Type', ''), ('sgprs', 'SGPRs', 'SGPRs', ''), ('vgprs', 'VGPRs', 'VGPRs', ''), ('spilled_sgprs', 'Spilled SGPRs', 'SpillS', ''), @@ -111,13 +114,13 @@ class si_stats: ('es_outputs', 'ES Outputs', 'ESOuts', ''), ('gs_outputs', 'GS Outputs', 'GSOuts', ''), ('vs_outputs', 'VS Outputs', 'VSOuts', ''), - ('inline_uniforms', 'Inline Uniforms', 'InliUni', '') + ('inline_uniforms', 'Inline Uniforms', 'InliUni', ''), ] def __init__(self): self.error = False - for name in self.get_metrics(): + for name in self.get_metrics_all_names(): self.__dict__[name] = 0 self._minmax_testname = {} @@ -126,7 +129,7 @@ class si_stats: copy = si_stats() copy.error = self.error - for name in self.get_metrics(): + for name in self.get_metrics_all_names(): copy.__dict__[name] = self.__dict__[name] copy._minmax_testname = self._minmax_testname.copy() @@ -135,7 +138,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.get_metrics(): string = " {}: {}".format(printname, get_str(self.__dict__[name])) if suffixes and len(suffix) > 0: @@ -148,18 +151,24 @@ class si_stats: strings.append(string + '\n') return ''.join(strings) - def get_metrics(self): + def get_metrics_all_names(self): return [m[0] for m in si_stats.metrics] + def get_metrics_names(self): + return [m[0] for m in si_stats.metrics[1:]] + + def get_metrics(): + return si_stats.metrics[1:] + def __str__(self): return self.to_string() def add(self, other): - for name in self.get_metrics(): + for name in self.get_metrics_names(): self.__dict__[name] += other.__dict__[name] def update(self, comp, cmp_fn, testname): - for name in self.get_metrics(): + for name in self.get_metrics_names(): current = self.__dict__[name] if type(current) != tuple: current = (0, 0, 0) @@ -168,7 +177,7 @@ class si_stats: self._minmax_testname[name] = testname def update_max(self, comp): - for name in self.get_metrics(): + for name in self.get_metrics_names(): current = self.__dict__[name] if type(current) == tuple: current = self.__dict__[name][0] @@ -176,7 +185,7 @@ class si_stats: self.__dict__[name] = comp.__dict__[name] def update_min(self, comp): - for name in self.get_metrics(): + for name in self.get_metrics_names(): current = self.__dict__[name] if type(current) == tuple: current = self.__dict__[name][0] @@ -184,17 +193,17 @@ class si_stats: self.__dict__[name] = comp.__dict__[name] def update_increase(self, comp): - for name in self.get_metrics(): + for name in self.get_metrics_names(): if comp.__dict__[name][0] > 0: self.__dict__[name] += 1 def update_decrease(self, comp): - for name in self.get_metrics(): + for name in self.get_metrics_names(): if comp.__dict__[name][0] < 0: self.__dict__[name] += 1 def is_empty(self): - for name in self.get_metrics(): + for name in self.get_metrics_names(): x = self.__dict__[name] if type(x) == tuple and x[0] != 0: return False @@ -210,20 +219,7 @@ class si_parser(object): 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]+) PSOutputs: [0-9]+ InlineUniforms: ([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( - 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]+)"), - 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]+)"), + r"VSOutputs: ([0-9]+) PSOutputs: [0-9]+ InlineUniforms: ([0-9]+) .*\(([VTCSEGPC]S),"), ] def __init__(self): @@ -264,6 +260,7 @@ class si_parser(object): self._stats.gs_outputs = int(match.group(14)) if match.lastindex >= 15 else 0 self._stats.vs_outputs = int(match.group(15)) if match.lastindex >= 15 else 0 self._stats.inline_uniforms = int(match.group(16)) if match.lastindex >= 16 else 0 + self._stats.shader_type = match.group(17) if match.lastindex >= 17 else '' old_stats = self._stats self._stats = None return old_stats @@ -316,7 +313,7 @@ def get_results(filename): def compare_stats(before, after): result = si_stats() - for name in result.get_metrics(): + for name in result.get_metrics_names(): b = before.__dict__[name] a = after.__dict__[name] result.__dict__[name] = (a - b, b, a) @@ -325,13 +322,13 @@ def compare_stats(before, after): def subtract_stats(x, y): result = si_stats() - for name in result.get_metrics(): + for name in result.get_metrics_names(): result.__dict__[name] = x.__dict__[name] - y.__dict__[name] return result def is_different(before, after): - for field in before.get_metrics(): + for field in before.get_metrics_names(): if before.__dict__[field] != after.__dict__[field]: return True return False @@ -339,7 +336,7 @@ def is_different(before, after): def divide_stats(num, div): result = si_stats() - for name in result.get_metrics(): + for name in result.get_metrics_names(): if div.__dict__[name] == 0: result.__dict__[name] = num.__dict__[name] else: @@ -349,7 +346,7 @@ def divide_stats(num, div): def print_before_after_stats(before, after): result = si_stats() - for name in result.get_metrics(): + for name in result.get_metrics_names(): b = before.__dict__[name] a = after.__dict__[name] if b == 0: @@ -509,7 +506,7 @@ class grouped_stats: if not is_different(self.before, self.after): return - print(("|{:{app_width}}|{:{shader_width}}|" + "{}|" * len(si_stats.metrics)).format( + print(("|{:{app_width}}|{:{shader_width}}|" + "{}|" * len(si_stats.get_metrics())).format( name, self.num_shaders, format_percent_change(self.before.sgprs, self.after.sgprs), @@ -526,12 +523,12 @@ class grouped_stats: format_percent_change(self.before.es_outputs, self.after.es_outputs), format_percent_change(self.before.gs_outputs, self.after.gs_outputs), format_percent_change(self.before.vs_outputs, self.after.vs_outputs), - format_percent_change(self.before.inline_uniforms, self.after.inline_uniforms), + format_percent_change(self.before.inline_uniforms, self.after.inline_uniforms, more_is_better=True), app_width=align, shader_width=len(legend[0]))) def print_regression(self, name, field): - more_is_better = field == "maxwaves" + more_is_better = field == "maxwaves" or field == "inline_uniforms" print(" {:6}{:6} {} {} {:90}".format( self.before.__dict__[field], self.after.__dict__[field], @@ -542,19 +539,6 @@ class grouped_stats: name)) -""" -Return "filename [index]", because files can contain multiple shaders. -""" -def get_shader_name(list, orig): - for i in range(10): - # add the index to the name - name = orig + " [{}]".format(i) - if name not in list: - return name - assert False - return "(error)" - - def print_yellow(str): print(set_yellow + str + set_normal) @@ -605,7 +589,7 @@ def print_tables(before_all_results, after_all_results): after.spilled_vgprs > 0 or after.privmem_vgprs > 0 or after.spilled_sgprs > 0): - name = get_shader_name(shaders, file) + name = file + ' - ' + after.shader_type shaders[name].set_one_shader(before, after) # worst VGPR spills @@ -649,11 +633,11 @@ def print_tables(before_all_results, after_all_results): print("") # worst regressions - metrics = si_stats().metrics + metrics = si_stats.get_metrics() for i in range(len(metrics)): field = metrics[i][0] num = 0 - more_is_better = metrics[i][0] == 'maxwaves' + more_is_better = metrics[i][0] == 'maxwaves' or metrics[i][0] == 'inline_uniforms' if more_is_better: sort_key = lambda v: v[1].diff.__dict__[field] @@ -679,11 +663,10 @@ def print_tables(before_all_results, after_all_results): print("") # biggest improvements - metrics = si_stats().metrics for i in range(len(metrics)): field = metrics[i][0] num = 0 - more_is_better = metrics[i][0] == 'maxwaves' + more_is_better = metrics[i][0] == 'maxwaves' or metrics[i][0] == 'inline_uniforms' if more_is_better: sort_key = lambda v: -v[1].diff.__dict__[field] |