-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmemEventParse.py
132 lines (119 loc) · 3.78 KB
/
memEventParse.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
import pyparsing as pp
import sys
import pandas as pd
import matplotlib.pyplot as plt
if len(sys.argv) is not 4:
print("Usage:", sys.argv[0],
"<mem-events file> <max regions> <output plot>")
sys.exit(1)
filepath = sys.argv[1]
with open(filepath) as f:
lines = f.read()
integer=pp.Combine(pp.Optional(pp.Word('-')) + pp.Word(pp.nums))
real=pp.Combine(integer + pp.Literal('.') + integer)
hexa=pp.Combine(pp.Word('0x') + pp.Word(pp.alphanums))
string=pp.Word(pp.alphas)
push=pp.Keyword("PushRegion")
pop=pp.Keyword("PopRegion")
ls=pp.Optional(pp.LineEnd()) + pp.LineStart()
underName=pp.Word(pp.alphas+"_", pp.alphanums+"_"+" ")
comment=pp.Suppress(pp.Group(ls + pp.Keyword("#") + pp.SkipTo(pp.LineEnd())))
start=pp.Group(ls + real + push + pp.SkipTo('{',include=True) + pp.LineEnd())
start.setName('start')
body=pp.Group(ls + real + hexa + integer + string + string + pp.Optional(underName))
body.setName('body')
end=pp.Group(ls + real + pp.Keyword('}') + pop + pp.LineEnd())
end.setName('end')
if False: #change to True to debug parsing
start.setDebug()
body.setDebug()
end.setDebug()
stmt = pp.Forward()
stmt << (comment | start | body | end)
module_body = pp.OneOrMore(stmt)
parseTree = module_body.parseString(lines)
def getStackString(stack,s,maxDepth):
stackStr=''
if len(s) == 6: # capture the name of the view/allocation
stack.append(s[5])
# Omega_h 'Write allocation' frames need to be counted
# within their parent frame since their deallocation
# is in the parent frame
stackStr = ';'.join([i if i != "Write allocation" else '' for i in stack[0:maxDepth]])
if len(s) == 6:
stack.pop()
if len(stackStr) == 0:
stackStr = "root"
return stackStr
stacks={}
stack=[]
maxDepth=1
for s in parseTree.asList():
mem = 0
if "PushRegion" in s:
stack.append(s[2].strip())
if "PopRegion" in s:
stack.pop()
if "PushRegion" not in s and "PopRegion" not in s and "Cuda" in s:
mem = int(s[2])
stackStr = getStackString(stack,s,maxDepth)
# add the new stack to the dictionary
if stackStr not in stacks:
stacks[stackStr]=[0]
M=1024*1024*1024
stack=[]
#length needs to match the length of lists in 'stacks'
time=[0]
mem=[]
tot=0
for s in parseTree.asList():
if "PushRegion" in s:
stack.append(s[2].strip())
if "PopRegion" in s:
stack.pop()
if "PushRegion" not in s and "PopRegion" not in s and "Cuda" in s:
stackStr = getStackString(stack,s,maxDepth)
time.append(float(s[0]))
m = float(s[2])
tot += m
mem.append(tot/M)
for (k,v) in stacks.items():
last=stacks[k][-1]
if stackStr == k:
lpm = last + m/M
if lpm < 0: # area plots don't support negative values
stacks[k].append(0)
else:
stacks[k].append(lpm)
else:
stacks[k].append(last)
sortedStacks = sorted(stacks.items(), key=lambda e: max(e[1]),reverse=True)
bigStacks={'time':time}
bigStacks['other']=[]
i=0
maxEntries=int(sys.argv[2])
for (k,v) in sortedStacks:
if i < maxEntries:
bigStacks[k]=v
else:
o = bigStacks['other']
if not o:
bigStacks['other'] = v;
else:
bigStacks['other'] = [sum(x) for x in zip(o,v)]
i+=1
print('---begin: max mem stacks (region, maxGB) ---')
for (k,v) in bigStacks.items():
if k != 'time':
print(k,max(v))
print('---end: max mem stacks---')
df = pd.DataFrame(bigStacks)
f = plt.figure()
ax = df.plot.area(x='time')
#move the legend to the right of the plot
legendTitle="top "+str(maxEntries)+" largest memory usage regions"
ax.legend(title=legendTitle,bbox_to_anchor=(1,1))
ax.set_ylabel('gpu mem (GB)')
ax.set_xlabel('time (s)')
ax.set_title('gpu memory usage')
plt.savefig(sys.argv[3],bbox_inches='tight',dpi=200)