-
Notifications
You must be signed in to change notification settings - Fork 2
/
results.py
executable file
·167 lines (128 loc) · 5.09 KB
/
results.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import codecs
class QueueBenchmarkParams:
def __init__(self, platform, device, fingerprint, properties):
self.platform = platform
self.device = device
self.fingerprint = fingerprint
self.properties = dict(properties)
def __repr__(self):
return f"QueueBenchmarkParams(platform='{self.platform}', device='{self.device}', fingerprint='{self.fingerprint}', properties={self.properties})"
class EnqueueDequeueStatistics:
def __init__(self, num_enqueues, num_enqueue_attempts, num_dequeues, num_dequeue_attempts):
self.num_enqueues = num_enqueues
self.num_enqueue_attempts = num_enqueue_attempts
self.num_dequeues = num_dequeues,
self.num_dequeue_attempts = num_dequeue_attempts
class QueueOperationTimings:
def __init__(self, t_enqueue, t_enqueue_min, t_enqueue_max, t_dequeue, t_dequeue_min, t_dequeue_max):
self.t_enqueue = t_enqueue
self.t_enqueue_min = t_enqueue_min
self.t_enqueue_max = t_enqueue_max
self.t_dequeue = t_dequeue
self.t_dequeue_min = t_dequeue_min
self.t_dequeue_max = t_dequeue_max
class QueueOperationStatistics:
def __init__(self, num_operations, t_total, t_min, t_max):
self.num_operations = num_operations
self.t_total = t_total
self.t_min = t_min
self.t_max = t_max
def __add__(self, other):
return QueueOperationStatistics(
self.num_operations + other.num_operations,
self.t_total + other.t_total,
min(self.t_min, other.t_min),
max(self.t_max, other.t_max))
def __mul__(self, other):
return QueueOperationStatistics(
self.num_operations,
self.t_total * other,
self.t_min * other,
self.t_max * other)
class DataVisitorKernelTimes:
def visit(self, num_threads, t):
pass
def leave(self):
pass
class DataVisitorEqDqStats:
def visit(self, num_threads, t, queue_stats):
pass
def leave(self):
pass
class DataVisitorOpTimes:
def visit(self, num_threads, t, queue_stats, queue_timings):
pass
def leave(self):
pass
class DataVisitorOpStats:
def visit(self, num_threads, t, enqueue_stats_succ, enqueue_stats_fail, dequeue_stats_succ, dequeue_stats_fail):
pass
def leave(self):
pass
class DatasetVisitor:
def visit_kernel_times(self):
return DataVisitorKernelTimes()
def visit_eqdq_stats(self):
return DataVisitorEqDqStats()
def visit_op_times(self):
return DataVisitorOpTimes()
def visit_op_stats(self):
return DataVisitorOpStats()
class Dataset:
def __init__(self, params, path, data_offset):
self.params = params
self.path = path
self.data_offset = data_offset
def __repr__(self):
return f"Dataset({self.params})"
@staticmethod
def make_sink(visitor, header):
parse_kernel_times = lambda cols: (int(cols[0]), float(cols[1]))
parse_eqdq_stats = lambda cols: EnqueueDequeueStatistics(int(cols[2]), int(cols[3]), int(cols[4]), int(cols[5]))
parse_op_times = lambda cols: QueueOperationTimings(int(cols[6]), int(cols[7]), int(cols[8]), int(cols[9]), int(cols[10]), int(cols[11]))
if len(header) == 2:
data_visitor = visitor.visit_kernel_times()
return lambda cols: data_visitor.visit(*parse_kernel_times(cols)), data_visitor
if len(header) == 6:
data_visitor = visitor.visit_eqdq_stats()
return lambda cols: data_visitor.visit(*parse_kernel_times(cols), parse_eqdq_stats(cols)), data_visitor
if len(header) == 12:
data_visitor = visitor.visit_op_times()
return lambda cols: data_visitor.visit(*parse_kernel_times(cols), parse_eqdq_stats(cols), parse_op_times(cols)), data_visitor
if len(header) == 18:
data_visitor = visitor.visit_op_stats()
def parse(cols):
enqueue_stats_succ = QueueOperationStatistics(int(cols[ 2]), int(cols[ 3]), int(cols[ 4]), int(cols[ 5]))
enqueue_stats_fail = QueueOperationStatistics(int(cols[ 6]), int(cols[ 7]), int(cols[ 8]), int(cols[ 9]))
dequeue_stats_succ = QueueOperationStatistics(int(cols[10]), int(cols[11]), int(cols[12]), int(cols[13]))
dequeue_stats_fail = QueueOperationStatistics(int(cols[14]), int(cols[15]), int(cols[16]), int(cols[17]))
return data_visitor.visit(*parse_kernel_times(cols), enqueue_stats_succ, enqueue_stats_fail, dequeue_stats_succ, dequeue_stats_fail)
return parse, data_visitor
raise Exception("invalid file format")
def visit(self, visitor):
with open(self.path, "rt") as file:
file.seek(self.data_offset)
header = next(file).split(';')
sink, data_visitor = Dataset.make_sink(visitor, header)
for l in file:
cols = l.split(';')
sink(cols)
data_visitor.leave()
return visitor
def parse_benchmark_output_header(file):
try:
params = codecs.decode(next(file)).strip().split(';')
values = codecs.decode(next(file)).strip().split(';')
next(file)
next(file)
config = codecs.decode(next(file)).split(';')
platform, device = config[0].strip(), config[1].strip()
fingerprint = config[2].strip() if len(config) > 2 else None
next(file)
return QueueBenchmarkParams(platform, device, fingerprint, zip(params, values))
except (StopIteration, ValueError, TypeError):
raise Exception("failed to parse benchmark output")
def read_benchmark_output(path):
with open(path, "rb") as file:
params = parse_benchmark_output_header(file)
return Dataset(params, path, file.tell())