Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / histogram / doc / fill_performance.py
1 #!/usr/bin/env python3
2
3 #            Copyright Hans Dembinski 2018 - 2019.
4 #   Distributed under the Boost Software License, Version 1.0.
5 #      (See accompanying file LICENSE_1_0.txt or copy at
6 #            https://www.boost.org/LICENSE_1_0.txt)
7
8 import os
9 import numpy as np
10 import glob
11 import re
12 import json
13 import sys
14 from collections import defaultdict, OrderedDict
15 from matplotlib.patches import Rectangle
16 from matplotlib.lines import Line2D
17 from matplotlib.text import Text
18 from matplotlib.font_manager import FontProperties
19 import matplotlib.pyplot as plt
20 import matplotlib as mpl
21
22 mpl.rcParams.update(mpl.rcParamsDefault)
23
24 cpu_frequency = 0
25
26 data = defaultdict(lambda: [])
27 for fn in sys.argv[1:]:
28     d = json.load(open(fn))
29     cpu_frequency = d["context"]["mhz_per_cpu"]
30     for bench in d["benchmarks"]:
31         name = bench["name"]
32         time = min(bench["cpu_time"], bench["real_time"])
33         m = re.match("fill_(n_)?([0-9])d<([^>]+)>", name)
34         if m.group(1):
35             time /= 1 << 15
36         tags = m.group(3).split(", ")
37         dim = int(m.group(2))
38         label = re.search(
39             "fill_([a-z]+)", os.path.splitext(os.path.split(fn)[1])[0]
40         ).group(1)
41         dist = tags[0]
42         if len(tags) > 1 and tags[1] in ("dynamic_tag", "static_tag"):
43             if len(tags) == 3 and "DStore" in tags[2]:
44                 continue
45             label += "-" + {"dynamic_tag": "dyn", "static_tag": "sta"}[tags[1]]
46             label += "-fill" if m.group(1) else "-call"
47         data[dim].append((label, dist, time / dim))
48
49 time_per_cycle_in_ns = 1.0 / (cpu_frequency * 1e6) / 1e-9
50
51 plt.figure(figsize=(7, 6))
52 i = 0
53 for dim in sorted(data):
54     v = data[dim]
55     labels = OrderedDict()
56     for label, dist, time in v:
57         if label in labels:
58             labels[label][dist] = time / time_per_cycle_in_ns
59         else:
60             labels[label] = {dist: time / time_per_cycle_in_ns}
61     j = 0
62     for label, d in labels.items():
63         t1 = d["uniform"]
64         t2 = d["normal"]
65         i -= 1
66         z = float(j) / len(labels)
67         col = (1.0 - z) * np.array((1.0, 0.0, 0.0)) + z * np.array((1.0, 1.0, 0.0))
68         if label == "root":
69             col = "k"
70             label = "ROOT 6"
71         if "numpy" in label:
72             col = "0.6"
73         if "gsl" in label:
74             col = "0.3"
75             label = "GSL"
76         tmin = min(t1, t2)
77         tmax = max(t1, t2)
78         r1 = Rectangle((0, i), tmax, 1, facecolor=col)
79         r2 = Rectangle(
80             (tmin, i), tmax - tmin, 1, facecolor="none", edgecolor="w", hatch="//////"
81         )
82         plt.gca().add_artist(r1)
83         plt.gca().add_artist(r2)
84         font = FontProperties(size=9)
85         tx = Text(
86             -0.5,
87             i + 0.5,
88             "%s" % label,
89             fontproperties=font,
90             va="center",
91             ha="right",
92             clip_on=False,
93         )
94         plt.gca().add_artist(tx)
95         j += 1
96     i -= 1
97     font = FontProperties()
98     font.set_weight("bold")
99     tx = Text(
100         -0.5,
101         i + 0.6,
102         "%iD" % dim,
103         fontproperties=font,
104         va="center",
105         ha="right",
106         clip_on=False,
107     )
108     plt.gca().add_artist(tx)
109 plt.ylim(0, i)
110 plt.xlim(0, 80)
111
112 plt.tick_params("y", left=False, labelleft=False)
113 plt.xlabel("average CPU cycles per random input value (smaller is better)")
114
115 plt.tight_layout()
116
117 plt.savefig("fill_performance.svg")
118 plt.show()