|
@@ -9,8 +9,8 @@ import utils
|
|
|
|
|
|
# pylint: disable=I0011,W0141
|
|
|
|
|
|
-COLOR_SCHEME_MIN_COLOR = (36, 255, 106)
|
|
|
-COLOR_SCHEME_MAX_COLOR = (216, 33, 0)
|
|
|
+COLOR_SCHEME_MAX_COLOR = (36, 255, 106)
|
|
|
+COLOR_SCHEME_MIN_COLOR = (216, 33, 0)
|
|
|
|
|
|
LATEX_HEADER = r"""\documentclass[12pt,a4paper,onecolumn,openright]{report}
|
|
|
\usepackage[landscape]{geometry}
|
|
@@ -28,18 +28,21 @@ LATEX_DOCUMENT_HEADER = r"""\begin{document}
|
|
|
LATEX_DOCUMENT_FOOTER = r"""\end{tikzpicture}
|
|
|
\end{document}"""
|
|
|
|
|
|
+
|
|
|
def encode_latex_string(value):
|
|
|
"""Encodes the given string as a LaTeX string."""
|
|
|
# I guess this is good enough for now. This may need to be
|
|
|
# revisited if we encounter more complicated names.
|
|
|
return '{%s}' % value.replace('_', '\\_')
|
|
|
|
|
|
+
|
|
|
def assemble_latex_chart(optimization_levels, color_defs, test_names, data):
|
|
|
"""Assembles a LaTeX chart from the given components."""
|
|
|
lines = []
|
|
|
lines.append(LATEX_HEADER)
|
|
|
for color_name, (red, green, blue) in color_defs:
|
|
|
- lines.append(r'\definecolor{%s}{HTML}{%02X%02X%02X}' % (color_name, red, green, blue))
|
|
|
+ lines.append(r'\definecolor{%s}{HTML}{%02X%02X%02X}' %
|
|
|
+ (color_name, red, green, blue))
|
|
|
lines.append(LATEX_DOCUMENT_HEADER)
|
|
|
lines.append(r"""
|
|
|
\begin{axis}[
|
|
@@ -66,20 +69,23 @@ def assemble_latex_chart(optimization_levels, color_defs, test_names, data):
|
|
|
for color_name, points in data:
|
|
|
lines.append(r"""
|
|
|
\addplot[style={%s,fill=%s,mark=none}]
|
|
|
- coordinates {%s};""" % (
|
|
|
- color_name, color_name,
|
|
|
- ' '.join([('(%s,%s)' % (encode_latex_string(name), measurement))
|
|
|
- for name, measurement in points])))
|
|
|
+ coordinates {%s};""" % (color_name, color_name, ' '.join(
|
|
|
+ [('(%s,%s)' % (encode_latex_string(name), measurement))
|
|
|
+ for name, measurement in points])))
|
|
|
lines.append(r"""
|
|
|
- \legend{%s}""" % ','.join(map(encode_latex_string, optimization_levels)))
|
|
|
+ \legend{%s}""" %
|
|
|
+ ','.join(map(encode_latex_string, optimization_levels)))
|
|
|
lines.append(r"""
|
|
|
\end{axis}""")
|
|
|
lines.append(LATEX_DOCUMENT_FOOTER)
|
|
|
return '\n'.join(lines)
|
|
|
|
|
|
-def create_latex_chart(perf_data):
|
|
|
+
|
|
|
+def create_latex_chart(perf_data, sorted_opt_levels=None):
|
|
|
"""Creates a LaTeX chart for the given performance data."""
|
|
|
- sorted_opt_levels = sort_by_runtime(perf_data)
|
|
|
+ if sorted_opt_levels is None:
|
|
|
+ sorted_opt_levels = sort_by_runtime(perf_data)
|
|
|
+
|
|
|
color_scheme = generate_color_scheme(sorted_opt_levels)
|
|
|
opt_levels = []
|
|
|
color_defs = []
|
|
@@ -98,6 +104,7 @@ def create_latex_chart(perf_data):
|
|
|
|
|
|
return assemble_latex_chart(opt_levels, color_defs, test_names, data)
|
|
|
|
|
|
+
|
|
|
def get_mean_runtimes(perf_data):
|
|
|
"""Computes the mean run-time of every optimization level in the given
|
|
|
performance data."""
|
|
@@ -106,6 +113,7 @@ def get_mean_runtimes(perf_data):
|
|
|
for opt_level in perf_data.keys()
|
|
|
}
|
|
|
|
|
|
+
|
|
|
def get_baseline_optimization_level(perf_data):
|
|
|
"""Gets a baseline optimization level from the given performance data.
|
|
|
This baseline optimization level is guaranteed to be for every test case.
|
|
@@ -126,7 +134,9 @@ def get_baseline_optimization_level(perf_data):
|
|
|
return None
|
|
|
|
|
|
# Pick the optimization level with the lowest total run-time as the baseline.
|
|
|
- return min(candidate_opt_levels, key=lambda opt_level: sum(perf_data[opt_level].values()))
|
|
|
+ return min(candidate_opt_levels,
|
|
|
+ key=lambda opt_level: sum(perf_data[opt_level].values()))
|
|
|
+
|
|
|
|
|
|
def get_relative_measurements(perf_data, baseline_optimization_level):
|
|
|
"""Computes a map of measurements that are relative to the given optimization level."""
|
|
@@ -139,13 +149,17 @@ def get_relative_measurements(perf_data, baseline_optimization_level):
|
|
|
|
|
|
return results
|
|
|
|
|
|
+
|
|
|
def perf_list_to_dict(perf_list):
|
|
|
"""Converts performance data from a list representation to a dictionary representation."""
|
|
|
return {opt_level: dict(tests) for opt_level, tests in perf_list}
|
|
|
|
|
|
+
|
|
|
def perf_dict_to_list(perf_dict):
|
|
|
"""Converts performance data from a dictionary representation to a list representation."""
|
|
|
- return [(opt_level, tests.items()) for opt_level, tests in perf_dict.items()]
|
|
|
+ return [(opt_level, tests.items())
|
|
|
+ for opt_level, tests in perf_dict.items()]
|
|
|
+
|
|
|
|
|
|
def interpolate(value_range, index, length):
|
|
|
"""Uses an index and a length to interpolate in the given range."""
|
|
@@ -155,13 +169,19 @@ def interpolate(value_range, index, length):
|
|
|
else:
|
|
|
return min_val + float(index) * (max_val - min_val) / float(length - 1)
|
|
|
|
|
|
+
|
|
|
def sort_by_runtime(perf_data):
|
|
|
"""Sorts the optimization levels by mean relative runtimes."""
|
|
|
baseline_opt_level = get_baseline_optimization_level(perf_data)
|
|
|
relative_perf = get_relative_measurements(perf_data, baseline_opt_level)
|
|
|
# Sort the optimization levels by their mean runtimes.
|
|
|
mean_runtimes = get_mean_runtimes(relative_perf)
|
|
|
- return list(sorted(mean_runtimes.keys(), key=lambda opt_level: mean_runtimes[opt_level]))
|
|
|
+ return list(
|
|
|
+ sorted(
|
|
|
+ mean_runtimes.keys(),
|
|
|
+ key=lambda opt_level: mean_runtimes[opt_level],
|
|
|
+ reverse=True))
|
|
|
+
|
|
|
|
|
|
def generate_color_scheme(sorted_opt_levels):
|
|
|
"""Assigns a color to every optimization level in the given performance data."""
|
|
@@ -175,38 +195,51 @@ def generate_color_scheme(sorted_opt_levels):
|
|
|
hue = interpolate((min_hue, max_hue), i, len(sorted_opt_levels))
|
|
|
sat = interpolate((min_sat, max_sat), i, len(sorted_opt_levels))
|
|
|
val = interpolate((min_val, max_val), i, len(sorted_opt_levels))
|
|
|
- color = [component * 255 for component in colorsys.hsv_to_rgb(hue, sat, val)]
|
|
|
+ color = [
|
|
|
+ component * 255 for component in colorsys.hsv_to_rgb(hue, sat, val)
|
|
|
+ ]
|
|
|
color_scheme[opt_level] = color
|
|
|
|
|
|
return color_scheme
|
|
|
|
|
|
+
|
|
|
def main():
|
|
|
arg_parser = argparse.ArgumentParser()
|
|
|
arg_parser.add_argument('input', help='The performance data file.')
|
|
|
arg_parser.add_argument(
|
|
|
- '-q', '--quantity', type=str,
|
|
|
- help="The quantity to build a bar chart for. Defaults to '%s'" % utils.TOTAL_TIME_QUANTITY,
|
|
|
+ '-q',
|
|
|
+ '--quantity',
|
|
|
+ type=str,
|
|
|
+ help="The quantity to build a bar chart for. Defaults to '%s'" %
|
|
|
+ utils.TOTAL_TIME_QUANTITY,
|
|
|
default=utils.TOTAL_TIME_QUANTITY)
|
|
|
arg_parser.add_argument(
|
|
|
- '-O', '--opt', type=str, nargs='*',
|
|
|
+ '-O',
|
|
|
+ '--opt',
|
|
|
+ type=str,
|
|
|
+ nargs='*',
|
|
|
help="Filters on optimization levels.")
|
|
|
arg_parser.add_argument(
|
|
|
- '-t', '--test', type=str, nargs='*',
|
|
|
- help="Filters on tests.")
|
|
|
+ '-t', '--test', type=str, nargs='*', help="Filters on tests.")
|
|
|
arg_parser.add_argument(
|
|
|
- '-r', '--relative', action='store_const', const=True,
|
|
|
- help="Produce bars that are relative to some baseline.", default=False)
|
|
|
+ '-r',
|
|
|
+ '--relative',
|
|
|
+ action='store_const',
|
|
|
+ const=True,
|
|
|
+ help="Produce bars that are relative to some baseline.",
|
|
|
+ default=False)
|
|
|
|
|
|
args = arg_parser.parse_args()
|
|
|
|
|
|
perf_data = utils.parse_perf_data(args.input)[args.quantity]
|
|
|
+ sorted_opt_levels = None
|
|
|
|
|
|
if args.opt:
|
|
|
optimization_set = set(args.opt)
|
|
|
- perf_data = [
|
|
|
- (optimization_level, measurements)
|
|
|
- for optimization_level, measurements in perf_data
|
|
|
- if optimization_level in optimization_set]
|
|
|
+ perf_data = [(optimization_level, measurements)
|
|
|
+ for optimization_level, measurements in perf_data
|
|
|
+ if optimization_level in optimization_set]
|
|
|
+ sorted_opt_levels = list(args.opt)
|
|
|
|
|
|
if args.test:
|
|
|
test_set = set(args.test)
|
|
@@ -225,9 +258,11 @@ def main():
|
|
|
|
|
|
if args.relative:
|
|
|
baseline_opt_level = get_baseline_optimization_level(perf_data_dict)
|
|
|
- perf_data_dict = get_relative_measurements(perf_data_dict, baseline_opt_level)
|
|
|
+ perf_data_dict = get_relative_measurements(perf_data_dict,
|
|
|
+ baseline_opt_level)
|
|
|
+
|
|
|
+ print(create_latex_chart(perf_data_dict, sorted_opt_levels))
|
|
|
|
|
|
- print(create_latex_chart(perf_data_dict))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
main()
|