summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2025-07-08 06:43:57 -0400
committerMarek Olšák <marek.olsak@amd.com>2025-07-10 06:37:43 -0400
commit080ccd9af7142a3878d12ed6c406580e4aba33ad (patch)
treee2593d965a601b311ade00effd4ce2e68ada6acb
parentd17b405c6e85ad9b3e1ca2acb6aea16e7223b884 (diff)
si-report.py: improve output
-rwxr-xr-xsi-report.py89
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]