-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplot.py
152 lines (121 loc) · 4.5 KB
/
plot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import numpy as np
import matplotlib.pyplot as plt
import os
from pathlib import Path
# source myenv/bin/activate
import numpy as np
import matplotlib.pyplot as plt
colors = {
'Board': "#F8CECC", #(0.12156862745098039, 0.4666666666666667, 0.7058823529411765),
'Offload': "#D5E8D4", #(1.0, 0.4980392156862745, 0.054901960784313725),
'Protect': "#DAE8FC", #(0.17254901960784313, 0.6274509803921569, 0.17254901960784313),
'Keystone': "#D5E8D4"# "#FFF2CC", #(0.8392156862745098, 0.15294117647058825, 0.1568627450980392),
}
curve_colors = {
'Board': "#B85450",
'Offload': "#82B366",
'Protect': "#6C8EBF",
}
names = {
'Board' : 'Native',
'Protect' : 'System no-offload',
'Offload' : 'System',
'Keystone' : 'Keystone enclave on System'
}
hatches = {
'Board' : 'xx',
'Protect' : '//',
'Offload' : '\\\\',
'Keystone' : '\\\\'
}
markers = {
'Board' : '1',
'Protect' : '3',
'Offload' : '2',
'Keystone' : '+'
}
WITH_OFFLOAD=True
TITLE=""
# HARDWARE="premier"
HARDWARE="visionfive2"
def plot_bar(x_ticks, data, path, native_performance, offset_unit, untily, ymin: float = 0, figsize = (8, 6), fontsize=None, valfontsize=10, legendsize=None, tick_rotation=0, val_shift=False, ncols=1, split=False, split_labels=None, split_label_height=1.0, columnspacing=None):
x = np.arange(len(x_ticks), dtype=np.float64) # the label locations
if split:
x[len(x)//2:] += 0.2
print(x)
width = 0.25 # the width of the bars
multiplier = 0
if len(data) == 2:
width = 0.33
fig, ax = plt.subplots(layout='constrained', figsize=figsize)
for i, (attribute, measurement) in enumerate(data.items()):
if attribute == "Offload" and not WITH_OFFLOAD:
continue
offset = width * multiplier
rects = ax.bar(x + offset, measurement, width, hatch=hatches[attribute], label=names[attribute], color=colors[attribute], edgecolor='black', linewidth=1.5)
multiplier += 1
# Add labels, title, and legend
ax.set_ylabel('Relative performance', fontsize=legendsize if legendsize is not None else fontsize)
ax.set_xticks(x + width, x_ticks, fontsize=fontsize, rotation=tick_rotation)
ax.tick_params(labelsize=fontsize)
ax.axhline(y=1, color='black', linestyle='--')
ax.set_ylim(ymin, untily)
if ncols == 1:
ax.legend(loc='lower right', fontsize=fontsize, columnspacing=columnspacing)
else:
ax.legend(loc='lower center', fontsize=fontsize, ncols=ncols, columnspacing=columnspacing)
if len(data) == 2:
width /= 2
# Add another set of x_ticks on top
ax.set_xticks(x + width, x_ticks)
ax.set_xticklabels(x_ticks) # This will add the regular x_ticks below
# Annotate "test" for each x-tick on top
for i, xtick in enumerate(x_ticks):
shift = 0
if val_shift:
shift = 2 * ((i + 1) % 2) - 1 # +/- 1
shift *= 0.03 # scale shift
ax.annotate(
native_performance[i],
xy=(x[i] + width, offset_unit + shift), # Shift the annotation a little to the right
ha='center',
va='bottom',
fontsize=valfontsize,
color='black'
)
if split_labels is not None:
n = len(x)
middle = (x[n//2 - 1] + x[n//2 + 1]) / 2
ax.annotate(
split_labels[0],
xy=(middle * 0.5 - width, split_label_height),
ha='center',
va='bottom',
fontsize=fontsize,
color='black'
)
ax.annotate(
split_labels[1],
xy=(middle * 1.5 - width, split_label_height),
ha='center',
va='bottom',
fontsize=fontsize,
color='black'
)
plt.suptitle(TITLE)
plt.savefig(f"plots/{path}_{HARDWARE}.pdf", format="pdf")
def extract_workload(file_path):
return str(file_path).split('/')[-1].split('_')[1]
def extract_iteration(file_path):
return int(str(file_path).split('/')[-1].split('_')[2].split('.')[0])
def is_workload(file_path, name):
return str(file_path).split('/')[-1].startswith(f"{name}_") and "stats" not in str(file_path)
def extract(key, extractor, path=f"results_{HARDWARE}"):
folder_path = Path(path)
output = []
for file_path in sorted(folder_path.rglob('*')):
# Recursively search all files
if is_workload(file_path, key):
print(file_path)
output.append((extract_workload(file_path),extractor(file_path)))
return output