From ab79d6dd7d9d5424ac16fb026ecfb88881df972e Mon Sep 17 00:00:00 2001 From: Patrick Bellasi Date: Wed, 24 Apr 2019 18:24:06 +0100 Subject: [PATCH 1/3] wltests/wa_results_collector: fix docs and cosmetics Signed-off-by: Patrick Bellasi --- lisa/wa_results_collector.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lisa/wa_results_collector.py b/lisa/wa_results_collector.py index 14a37ef94..95b94d4f2 100644 --- a/lisa/wa_results_collector.py +++ b/lisa/wa_results_collector.py @@ -907,18 +907,25 @@ class WaResultsCollector(Loggable): under Jankbench, so default parameters are provided to make this easy. :param workload: Name of workload to display metrics for + :type workload: str + :param metric: Name of metric to display + :type metric: str :param threshold: Value to highlight in the plot - the likely use for this is highlighting the maximum acceptable frame-rendering time in order to see at a glance the rough proportion of frames that were rendered in time. + :type threshold: int :param tag: regular expression to filter tags that should be plotted + :type tag: int + :param kernel: regular expression to filter kernels that should be plotted - :param tag: regular expression to filter tags that should be plotted + :type kernel: int - :param by: List of identifiers to group output as in DataFrame.groupby. + :param tests: regular expression to filter tests that should be plotted + :type tests: str """ logger = self.get_logger() @@ -933,7 +940,7 @@ class WaResultsCollector(Loggable): colors = iter(cm.rainbow(np.linspace(0, 1, test_cnt+1))) fig, axes = plt.subplots() - axes.axvspan(0, threshold, facecolor='g', alpha=0.1); + axes.axvspan(0, threshold, facecolor='g', alpha=0.1) labels = [] lines = [] -- GitLab From c342945cf02fce3eda9acc477c9f42d1dfc78ee1 Mon Sep 17 00:00:00 2001 From: Patrick Bellasi Date: Wed, 24 Apr 2019 18:26:25 +0100 Subject: [PATCH 2/3] wltests/wa_results_collector: add sorted plot_cdf The CDF plot reports plots in a random dataframe way and set the plot title based on the last CDF plot added to the image. Encode the "below threshold" percentage in the legend to report the actual value for each test. Move the legend below the plot to ensure optimal visibility also for big datasets. Finally, ensure to plot the CDFs from the best to the worst thus making the legend even more useful. An optional parameter is added to specify the number of columns in the legend. Some more advanced code could try to figure out the best value based on labels length but, let's keep the code simple for the time being. Signed-off-by: Patrick Bellasi --- lisa/wa_results_collector.py | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/lisa/wa_results_collector.py b/lisa/wa_results_collector.py index 95b94d4f2..166aa18fa 100644 --- a/lisa/wa_results_collector.py +++ b/lisa/wa_results_collector.py @@ -894,7 +894,7 @@ class WaResultsCollector(Loggable): return self.CDF(df, threshold, above, below) def plot_cdf(self, workload='jankbench', metric='frame_total_duration', - threshold=16, tag='.*', kernel='.*', test='.*'): + threshold=16, ncol=5, tag='.*', kernel='.*', test='.*'): """ Display cumulative distribution functions of a certain metric @@ -918,6 +918,9 @@ class WaResultsCollector(Loggable): rough proportion of frames that were rendered in time. :type threshold: int + :param ncol: Number of columns in the legend, default: 5 + :type ncol: int + :param tag: regular expression to filter tags that should be plotted :type tag: int @@ -942,25 +945,33 @@ class WaResultsCollector(Loggable): fig, axes = plt.subplots() axes.axvspan(0, threshold, facecolor='g', alpha=0.1) + # Pre-compute CDFs to support sorted plotting + data = [] + for keys, df in df.groupby(['test', 'tag', 'kernel']): + cdf = self._get_cdf(df['value'], threshold) + data.append((keys, df, cdf)) + labels = [] lines = [] - for keys, df in df.groupby(['test', 'tag', 'kernel']): - labels.append("{:16s}: {:32s}".format(keys[2], keys[1])) + for (keys, df, cdf) in sorted(data, key=lambda x: x[2].below, + reverse=True): color = next(colors) - cdf = self._get_cdf(df['value'], threshold) - [units] = df['units'].unique() - ax = cdf.df.plot(ax=axes, legend=False, xlim=(0,None), figsize=(16, 6), - title='Total duration CDF ({:.1f}% within {} [{}] threshold)'\ - .format(100. * cdf.below, threshold, units), - label=test, - color=to_hex(color)) - lines.append(ax.lines[-1]) + cdf.df.plot(legend=False, xlim=(0,None), figsize=(16, 6), + label=test, color=to_hex(color)) + lines.append(axes.lines[-1]) axes.axhline(y=cdf.below, linewidth=1, linestyle='--', color=to_hex(color)) + labels.append("{:16s}: {:32s} ({:4.1f}%)".format( + keys[2], keys[1], 100. * cdf.below)) + logger.debug("%-32s: %-32s: %.1f", keys[2], keys[1], 100.*cdf.below) + [units] = df['units'].unique() + axes.set_title('Total duration CDFs (% within {} [{}] threshold)'\ + .format(threshold, units)) axes.grid(True) - axes.legend(lines, labels) + axes.legend(lines, labels, loc='upper left', + ncol=ncol, bbox_to_anchor=(0, -.15)) plt.show() def find_comparisons(self, base_id=None, by='kernel'): -- GitLab From 2bac685e88cb34a39fef3eed3121ebee1c56fd7f Mon Sep 17 00:00:00 2001 From: Patrick Bellasi Date: Wed, 24 Apr 2019 18:47:39 +0100 Subject: [PATCH 3/3] wltests/wa_results_collector: add plot_cdf count filter Now that plots are ordered, add a filter to limit the number of CDFs to plot. This can be conveniently used to report only the optimal solution on a big dataset. Signed-off-by: Patrick Bellasi --- lisa/wa_results_collector.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/lisa/wa_results_collector.py b/lisa/wa_results_collector.py index 166aa18fa..ba534f767 100644 --- a/lisa/wa_results_collector.py +++ b/lisa/wa_results_collector.py @@ -894,7 +894,8 @@ class WaResultsCollector(Loggable): return self.CDF(df, threshold, above, below) def plot_cdf(self, workload='jankbench', metric='frame_total_duration', - threshold=16, ncol=5, tag='.*', kernel='.*', test='.*'): + threshold=16, top_most=None, ncol=1, + tag='.*', kernel='.*', test='.*'): """ Display cumulative distribution functions of a certain metric @@ -918,7 +919,13 @@ class WaResultsCollector(Loggable): rough proportion of frames that were rendered in time. :type threshold: int - :param ncol: Number of columns in the legend, default: 5 + :param top_most: Maximum number of CDFs to plot, all available plots + if not specified + :type top_most: int + + :param ncol: Number of columns in the legend, default: 1. If more than + one column is requested the legend will be force placed + below the plot to avoid covering the data. :type ncol: int :param tag: regular expression to filter tags that should be plotted @@ -953,8 +960,10 @@ class WaResultsCollector(Loggable): labels = [] lines = [] + if top_most is None: + top_most = len(data) for (keys, df, cdf) in sorted(data, key=lambda x: x[2].below, - reverse=True): + reverse=True)[:top_most]: color = next(colors) cdf.df.plot(legend=False, xlim=(0,None), figsize=(16, 6), label=test, color=to_hex(color)) @@ -970,8 +979,12 @@ class WaResultsCollector(Loggable): axes.set_title('Total duration CDFs (% within {} [{}] threshold)'\ .format(threshold, units)) axes.grid(True) - axes.legend(lines, labels, loc='upper left', - ncol=ncol, bbox_to_anchor=(0, -.15)) + if ncol < 2: + axes.legend(lines, labels, loc='best') + else: + axes.legend(lines, labels, loc='upper left', + ncol=ncol, bbox_to_anchor=(0, -.15)) + plt.show() def find_comparisons(self, base_id=None, by='kernel'): -- GitLab