From 2480e28760ba32dbcc3ffc6a04b5519ecbf3725e Mon Sep 17 00:00:00 2001 From: Josh Milthorpe Date: Thu, 30 Nov 2023 07:31:57 +1100 Subject: [PATCH 01/10] use portable interpreter line; updates for Numpy, Matplotlib deprecations --- metrics/scripts/heatmap.py | 6 +++--- metrics/scripts/pp_vis.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/metrics/scripts/heatmap.py b/metrics/scripts/heatmap.py index 89aa2eb..9a8c43f 100755 --- a/metrics/scripts/heatmap.py +++ b/metrics/scripts/heatmap.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # Copyright (c) 2020 Performance Portability authors # SPDX-License-Identifier: MIT @@ -58,7 +58,7 @@ def get(name): def eff(a, b): if isinstance(a, float) and isinstance(b, float): return float(100.0 * (a / b)) - elif a is '-' or b is '-': + elif a == '-' or b == '-': return float(-100.0) else: return float(0.0) @@ -101,7 +101,7 @@ def eff(a, b): colors = "gist_heat" if not args.higher_is_better: colors = colors + "_r" -cmap = plt.cm.get_cmap(colors) +cmap = plt.get_cmap(colors) x = np.arange(7) y = np.arange(11) cmesh = plt.pcolormesh( diff --git a/metrics/scripts/pp_vis.py b/metrics/scripts/pp_vis.py index 582b225..7b67d69 100755 --- a/metrics/scripts/pp_vis.py +++ b/metrics/scripts/pp_vis.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3.7 +#!/usr/bin/env python3 # Copyright (c) 2020 Performance Portability authors # SPDX-License-Identifier: MIT @@ -232,7 +232,7 @@ def histogram(bins, data): def binplot(ax, app_effs, colordict=None): """Compute and plot histogram of dataframe app_effs onto axis ax. Use colors for each column as specified in colordict or compute manually. Bin 0 is handled specially and kept separate from others.""" - bins = np.arange(0, 1.1, 0.1, dtype=np.float) + bins = np.arange(0, 1.1, 0.1, dtype=float) bins[0] = np.finfo(float).eps bins = np.append(np.zeros(1), bins) bar_data = {} From c6934d23b4c57c63cf9b5e7ec665e63c30650934 Mon Sep 17 00:00:00 2001 From: Josh Milthorpe Date: Thu, 30 Nov 2023 07:32:49 +1100 Subject: [PATCH 02/10] data-dependent heatmap size --- metrics/scripts/heatmap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metrics/scripts/heatmap.py b/metrics/scripts/heatmap.py index 9a8c43f..fe108fd 100755 --- a/metrics/scripts/heatmap.py +++ b/metrics/scripts/heatmap.py @@ -102,8 +102,8 @@ def eff(a, b): if not args.higher_is_better: colors = colors + "_r" cmap = plt.get_cmap(colors) -x = np.arange(7) -y = np.arange(11) +x = np.arange(len(l)+1) +y = np.arange(len(heatmap)+1) cmesh = plt.pcolormesh( x, y, From 351c55b1f8412c2154a9d807005be3a2b2338018 Mon Sep 17 00:00:00 2001 From: Josh Milthorpe Date: Thu, 30 Nov 2023 09:34:14 +1100 Subject: [PATCH 03/10] replace removed DataFrame.append with pd.concat; return 0 for geomean if any input is 0 --- metrics/scripts/averages.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/metrics/scripts/averages.py b/metrics/scripts/averages.py index cdc96ae..d7d8286 100755 --- a/metrics/scripts/averages.py +++ b/metrics/scripts/averages.py @@ -7,7 +7,7 @@ import matplotlib.pyplot as plt import argparse -from statistics import mean, harmonic_mean, median +from statistics import mean, harmonic_mean, geometric_mean, median import math import sys @@ -16,7 +16,9 @@ def geomean(n): # geometric_mean was not added to statistics until Python 3.8 if (sys.version_info.major > 3) or ( sys.version_info.major == 3 and sys.version_info.minor >= 8): - return statistics.geometric_mean(n) + if 0 in n: + return 0 + return geometric_mean(n) else: return np.prod(n)**(1.0 / float(len(n))) @@ -70,7 +72,6 @@ def pp(n): args.input_file, skipinitialspace=True, sep=r',\s+', - delimiter=',', na_values='X') # In the case of trailing whitespace, the X don't get converted. @@ -124,7 +125,8 @@ def pp(n): for (name, f) in averages.items(): avg = data_nona.apply(f, raw=True).copy() avg.name = name - results = results.append(avg, ignore_index=False) + results = pd.concat([results, avg], axis=1, ignore_index=False) +results = results.transpose() # Sort columns according to their PP value # sort_index is not supported by old Pandas From 277aeada200d1ab9f54e75ae3ff423ee38e00f21 Mon Sep 17 00:00:00 2001 From: Josh Milthorpe Date: Fri, 8 Dec 2023 17:13:50 +1100 Subject: [PATCH 04/10] fix pandas concat, delimiter issues Don't display decimal point if value is an integer --- metrics/scripts/heatmap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metrics/scripts/heatmap.py b/metrics/scripts/heatmap.py index fe108fd..3bbdc80 100755 --- a/metrics/scripts/heatmap.py +++ b/metrics/scripts/heatmap.py @@ -83,7 +83,7 @@ def eff(a, b): else: l.append('%.0f%%' % (raw[i] / args.factorize)) else: - if raw[i] / args.factorize < 100.0: + if raw[i] / args.factorize < 100.0 and not raw[i].is_integer(): l.append('%.1f' % (raw[i] / args.factorize)) else: l.append('%.0f' % (raw[i] / args.factorize)) From e87190faa5ef87a171be0b6e0645b0d199a11559 Mon Sep 17 00:00:00 2001 From: Josh Milthorpe Date: Fri, 8 Dec 2023 17:30:23 +1100 Subject: [PATCH 05/10] mask out non-values, use viridis for colorblind viewing --- metrics/scripts/heatmap.py | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/metrics/scripts/heatmap.py b/metrics/scripts/heatmap.py index 3bbdc80..61fe5ec 100755 --- a/metrics/scripts/heatmap.py +++ b/metrics/scripts/heatmap.py @@ -70,7 +70,7 @@ def eff(a, b): continue series.append(result[series_key]) - heatmap.append([r if isinstance(r, float) else 0.0 for r in raw]) + heatmap.append([r if isinstance(r, float) else float('nan') for r in raw]) l = [] for i in range(len(raw)): @@ -89,38 +89,31 @@ def eff(a, b): l.append('%.0f' % (raw[i] / args.factorize)) labels.append(l) -plt.rcParams.update({ - "font.family": "serif", # use serif/main font for text elements - "text.usetex": False, # use inline math for ticks - "pgf.rcfonts": False, # don't setup fonts from rc parameters -}) +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif='Times') fig, ax = plt.subplots() -fig.set_size_inches(4, 3) # Set color map to match blackbody, growing brighter for higher values -colors = "gist_heat" +colors = "viridis" if not args.higher_is_better: colors = colors + "_r" cmap = plt.get_cmap(colors) x = np.arange(len(l)+1) y = np.arange(len(heatmap)+1) +masked = np.ma.masked_where(np.isnan(heatmap),heatmap) cmesh = plt.pcolormesh( x, y, - np.array(heatmap), + masked, cmap=cmap, edgecolors='k', vmin=1.0E-6) ax.set_yticks(np.arange(len(heatmap)) + 0.5, minor=False) ax.set_xticks(np.arange(len(heatmap[0])) + 0.5, minor=False) - -ax.set_yticklabels(series) +ax.set_yticklabels(series, fontsize='xx-large') for i in range(len(headings)): - heading = headings[i].replace('_', r'\_') - if not plt.rcParams['text.usetex']: - heading = heading.replace(r"\%", "%") - headings[i] = heading -ax.set_xticklabels(headings, rotation=45, ha="right", rotation_mode="anchor") + headings[i] = headings[i].replace('_', '\_') +ax.set_xticklabels(headings, fontsize='xx-large', rotation=45) plt.gca().invert_yaxis() # Add colorbar @@ -129,7 +122,7 @@ def eff(a, b): # Add labels for i in range(len(headings)): for j in range(len(series)): - plt.text(i + 0.9, j + 0.5, labels[j][i], - ha='right', va='center', color='#b9c5bf', fontsize='small') + plt.text(i + 0.5, j + 0.55, labels[j][i], + ha='center', va='center', color='#b9c5bf', weight='bold', size='xx-large') plt.savefig(args.output, bbox_inches='tight') From b714addce9d101c200fadd06886f1e141a7428a7 Mon Sep 17 00:00:00 2001 From: Josh Milthorpe Date: Mon, 11 Dec 2023 15:38:36 +1100 Subject: [PATCH 06/10] heatmap: display percentages to one decimal place --- metrics/scripts/heatmap.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/metrics/scripts/heatmap.py b/metrics/scripts/heatmap.py index 61fe5ec..b1cdbb3 100755 --- a/metrics/scripts/heatmap.py +++ b/metrics/scripts/heatmap.py @@ -47,6 +47,10 @@ heatmap = [] # empty, to be populated by reading the input file labels = [] # labels to display in each heatmap entry +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif='Times') +fig, ax = plt.subplots() + for result in data: def get(name): str = result[name] @@ -79,9 +83,9 @@ def eff(a, b): else: if args.percent: if plt.rcParams['text.usetex']: - l.append('%.0f\\%%' % (raw[i] / args.factorize)) + l.append('%.1f\\%%' % (raw[i] / args.factorize)) else: - l.append('%.0f%%' % (raw[i] / args.factorize)) + l.append('%.1f%%' % (raw[i] / args.factorize)) else: if raw[i] / args.factorize < 100.0 and not raw[i].is_integer(): l.append('%.1f' % (raw[i] / args.factorize)) @@ -89,10 +93,6 @@ def eff(a, b): l.append('%.0f' % (raw[i] / args.factorize)) labels.append(l) -plt.rc('text', usetex=True) -plt.rc('font', family='serif', serif='Times') -fig, ax = plt.subplots() - # Set color map to match blackbody, growing brighter for higher values colors = "viridis" if not args.higher_is_better: From af1a55034347a1787b01c29df9654e9a9c9b9499 Mon Sep 17 00:00:00 2001 From: Josh Milthorpe Date: Mon, 11 Dec 2023 15:40:02 +1100 Subject: [PATCH 07/10] colour labels white on dark background The viridis colormap is pretty dark for values in the first third of the range. Colour the labels white in this range to aid readability. --- metrics/scripts/heatmap.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/metrics/scripts/heatmap.py b/metrics/scripts/heatmap.py index b1cdbb3..f929863 100755 --- a/metrics/scripts/heatmap.py +++ b/metrics/scripts/heatmap.py @@ -51,6 +51,9 @@ plt.rc('font', family='serif', serif='Times') fig, ax = plt.subplots() +max_all = -np.inf +min_all = np.inf + for result in data: def get(name): str = result[name] @@ -75,6 +78,8 @@ def eff(a, b): series.append(result[series_key]) heatmap.append([r if isinstance(r, float) else float('nan') for r in raw]) + max_all = max(max_all, max(heatmap[len(heatmap)-1])) + min_all = min(min_all, min(heatmap[len(heatmap)-1])) l = [] for i in range(len(raw)): @@ -119,10 +124,18 @@ def eff(a, b): # Add colorbar plt.colorbar(cmesh) +one_third = min_all + (max_all - min_all) / 3.0 +two_thirds = min_all + 2.0 * (max_all - min_all) / 3.0 + # Add labels for i in range(len(headings)): for j in range(len(series)): + labelcolor = 'black' + if args.higher_is_better and heatmap[j][i] < one_third: + labelcolor='white' + elif not args.higher_is_better and heatmap[j][i] > two_thirds: + labelcolor='white' plt.text(i + 0.5, j + 0.55, labels[j][i], - ha='center', va='center', color='#b9c5bf', weight='bold', size='xx-large') + ha='center', va='center', color=labelcolor, weight='bold', size='xx-large') plt.savefig(args.output, bbox_inches='tight') From 0ce563d44dc7bba7b3d13fb0a9ae779da81f3c37 Mon Sep 17 00:00:00 2001 From: Josh Milthorpe Date: Mon, 11 Dec 2023 15:40:48 +1100 Subject: [PATCH 08/10] Pandas: use separator but not delimiter for CSV; use concat instead of append --- metrics/scripts/consistency.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metrics/scripts/consistency.py b/metrics/scripts/consistency.py index 7f6b8bd..c4b9430 100755 --- a/metrics/scripts/consistency.py +++ b/metrics/scripts/consistency.py @@ -113,7 +113,6 @@ def pp(n): args.input_file, skipinitialspace=True, sep=r',\s+', - delimiter=',', na_values='X') # In the case of trailing whitespace, the X don't get converted. @@ -167,7 +166,8 @@ def pp(n): for (name, f) in measures.items(): measure = data_nona.apply(f, raw=True).copy() measure.name = name - results = results.append(measure, ignore_index=False) + results = pd.concat([results, measure], axis=1, ignore_index=False) +results = results.transpose() # Sort columns according to their PP value # sort_index is not supported by old Pandas From 1bc67cbb4284e3251d1fe726f592008591d7ba5d Mon Sep 17 00:00:00 2001 From: Josh Milthorpe Date: Tue, 20 Feb 2024 21:33:16 +1100 Subject: [PATCH 09/10] updates to heatmap for percentage, color for range --- metrics/scripts/heatmap.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/metrics/scripts/heatmap.py b/metrics/scripts/heatmap.py index f929863..304d174 100755 --- a/metrics/scripts/heatmap.py +++ b/metrics/scripts/heatmap.py @@ -37,6 +37,8 @@ # Get the list of headings from first row headings = data.fieldnames[1:] +if len(headings) < 1: + raise Exception("No input fields found") # Name of the series, what the rows in the CSV actually are series_key = data.fieldnames[0] @@ -88,17 +90,24 @@ def eff(a, b): else: if args.percent: if plt.rcParams['text.usetex']: - l.append('%.1f\\%%' % (raw[i] / args.factorize)) + if raw[i] / args.factorize < 100.0: + l.append('%.1f\\%%' % (raw[i] / args.factorize)) + else: + l.append('%.0f\\%%' % (raw[i] / args.factorize)) else: - l.append('%.1f%%' % (raw[i] / args.factorize)) + if raw[i] / args.factorize < 100.0: + l.append('%.1f%%' % (raw[i] / args.factorize)) + else: + l.append('%.0f%%' % (raw[i] / args.factorize)) else: - if raw[i] / args.factorize < 100.0 and not raw[i].is_integer(): + if not raw[i].is_integer(): l.append('%.1f' % (raw[i] / args.factorize)) else: l.append('%.0f' % (raw[i] / args.factorize)) labels.append(l) # Set color map to match blackbody, growing brighter for higher values +fig.set_figwidth(fig.get_figwidth() / 5 * len(l)) colors = "viridis" if not args.higher_is_better: colors = colors + "_r" @@ -124,8 +133,10 @@ def eff(a, b): # Add colorbar plt.colorbar(cmesh) -one_third = min_all + (max_all - min_all) / 3.0 -two_thirds = min_all + 2.0 * (max_all - min_all) / 3.0 +#one_third = min_all + (max_all - min_all) / 3.0 +#two_thirds = min_all + 2.0 * (max_all - min_all) / 3.0 +one_third = max_all / 3.0 +two_thirds = 2.0 * max_all / 3.0 # Add labels for i in range(len(headings)): From cbea2acb6d57f7a4743c0edc1bb8eb0566735a95 Mon Sep 17 00:00:00 2001 From: Josh Milthorpe Date: Tue, 27 Feb 2024 13:50:01 +1100 Subject: [PATCH 10/10] cleanup --- metrics/scripts/heatmap.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/metrics/scripts/heatmap.py b/metrics/scripts/heatmap.py index 304d174..081c7ed 100755 --- a/metrics/scripts/heatmap.py +++ b/metrics/scripts/heatmap.py @@ -133,8 +133,6 @@ def eff(a, b): # Add colorbar plt.colorbar(cmesh) -#one_third = min_all + (max_all - min_all) / 3.0 -#two_thirds = min_all + 2.0 * (max_all - min_all) / 3.0 one_third = max_all / 3.0 two_thirds = 2.0 * max_all / 3.0