This repository has been archived by the owner on Aug 24, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtimeline.py
executable file
·153 lines (104 loc) · 3.82 KB
/
timeline.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
#!/usr/bin/env python
# coding=utf8
#
# (c) 2012 Matthias Bach <[email protected]>
import argparse
import re
class ProfileEntry:
def __init__(self, commandKey, commandName, commandStart, commandEnd):
self.key = int(commandKey)
self.name = commandName
self.start = int(commandStart)
self.end = int(commandEnd)
def isKernel(self):
return self.key == 66
def isMemcpy(self):
return self.key >= 52 and self.key <= 56
class DeviceEntry(ProfileEntry):
def __init__(self, commandKey, commandName, commandStart, commandEnd, deviceCommandKey, deviceCommandName, timeQueued, timeSubmitted, timeStarted, timeEnded, *args):
ProfileEntry.__init__(self, commandKey, commandName, commandStart, commandEnd)
self.deviceKey = int(deviceCommandKey)
self.deviceName = deviceCommandName
self.timeQueued = int(timeQueued)
self.timeSubmitted = int(timeSubmitted)
self.timeStarted = int(timeStarted)
self.timeEnded = int(timeEnded)
if self.isKernel():
self.kernelName = args[6]
if self.isMemcpy():
self.copyBytes = int(args[-1])
def isDeviceCommand(key):
"""Checks if the command will be executed on the device"""
return key >= 52 and key < 70
def parseAPT(aptfilename):
aptfile = open(aptfilename)
# expect first to lines to contain Trace File Version and Profiler Version
file_ver = re.match(r'TraceFileVersion=\d+\.\d+', aptfile.next())
app_ver = re.match(r'ProfilerVersion=\d+\.\d+.\d+', aptfile.next())
if not file_ver or not app_ver:
print 'Seems not to be an APP Profiler API trace file'
raise Exception('Invalid input file')
# fast forward until we reach the timestamp output
for tmp in aptfile:
if re.match('=====AMD APP Profiler Timestamp Output=====', tmp):
break
aptfile.next() # skip entry with unkown meaning
expected_count = int(aptfile.next())
# read all remaining lines (or until empty line)
entries = []
for tmp in aptfile:
line = tmp.split()
if len(line) == 0:
break
if isDeviceCommand(int(line[0])):
entry = DeviceEntry(*line)
else:
entry = ProfileEntry(*line[0:4])
entries.append(entry)
if len(entries) != expected_count:
print 'Warning: Expected {0} entries, but found {1} entries'.format(expected_count, len(entries))
return entries
def printCommandKeyList(aptfilename):
entries = parseAPT(aptfilename)
commands = {}
for entry in entries:
try:
check = commands[entry.key]
if check and check != entry.name:
print 'Error: Found key {0} for name "{1}", but already mapped to name "{2}"'.format(entry.key, entry.name, check)
return
except KeyError:
pass
commands[entry.key] = entry.name
for entry in commands.items():
print '{0:>5} {1}'.format(*entry)
def main(aptfilename):
entries = parseAPT(aptfilename)
last_device_end = 0
table_format = '{0:>10} {1}'
print 'Device Utilization'
print '=================='
print
print table_format.format('Time (ns)', 'Operation')
print
for entry in entries:
if isinstance(entry, DeviceEntry):
idle = entry.timeStarted - last_device_end
print table_format.format(idle, 'Idle')
duration = entry.timeEnded - entry.timeStarted
last_device_end = entry.timeEnded
if entry.isKernel():
description = entry.kernelName
elif entry.isMemcpy():
description = '{0} of {1} bytes'.format(entry.name, entry.copyBytes)
print table_format.format(duration, description)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Plot a timeline of the OpenCL events')
parser.add_argument('aptfile', metavar='FILE', help='The file containing the API trace generated by the APP Profiler')
advanced = parser.add_argument_group('Advanced')
advanced.add_argument('--list-keys', action='store_true', default=False, help='Print a list of command keys')
args = parser.parse_args()
if args.list_keys:
printCommandKeyList(args.aptfile)
else:
main(args.aptfile)