Script to convert from XML HPCToolkit format to callgrind
#!/usr/bin/env python | |
from xml.sax import ContentHandler, make_parser | |
from collections import defaultdict | |
class HPCToolKitHandler(ContentHandler): | |
def __init__(self, f): | |
self.f = f | |
self.metrics = {} | |
self.files = {} | |
self.functions = {} | |
self.cumulative_metrics = [defaultdict(int)] | |
self.strings = [] | |
self.stack = [] | |
def startElement(self, name, attrs): | |
if name == "MetricTable": | |
pass | |
elif name == "Metric": | |
self.process_metric(attrs) | |
elif name == "File": | |
self.process_file(attrs) | |
elif name == "Procedure": | |
self.process_procedure(attrs) | |
elif name == "PF": | |
self.process_PF(attrs) | |
elif name == "PR": | |
self.process_PF(attrs) | |
elif name == "S": | |
self.process_site(attrs) | |
elif name == "C": | |
self.process_call(attrs) | |
elif name == "M": | |
self.process_measure(attrs) | |
def endElement(self, name): | |
if name == "MetricTable": | |
self.dump_metrics() | |
elif name == "Metric": | |
pass | |
elif name == "File": | |
pass | |
elif name == "Procedure": | |
pass | |
elif name == "PF": | |
self.process_PF_end() | |
elif name == "PR": | |
self.process_PF_end() | |
elif name == "S": | |
self.process_site_end() | |
elif name == "C": | |
self.process_call_end() | |
elif name == "M": | |
pass | |
def dump_metrics(self): | |
self.metrics_keys = self.metrics.keys() | |
self.metrics_keys.sort() | |
self.f.write("events: " + " ".join(self.metrics[key] for key in self.metrics_keys) + "\n") | |
def process_metric(self, attrs): | |
i = -1 | |
name = None | |
for (k,v) in attrs.items(): | |
if k == "i": | |
i = int(v) | |
if k == "n": | |
name = v.replace(" ", "_") | |
self.metrics[i] = name | |
def process_measure(self, attrs): | |
i = -1 | |
value = 0 | |
for (k,v) in attrs.items(): | |
if k == "n": | |
i = int(v) | |
if k == "v": | |
value = int(float(v)) | |
self.cumulative_metrics[-1][i] = value | |
def process_file(self, attrs): | |
i = -1 | |
name = None | |
for (k,v) in attrs.items(): | |
if k == "i": | |
i = int(v) | |
elif k == "n": | |
name = v.replace(" ", "_") | |
self.files[i] = name | |
def process_procedure(self, attrs): | |
i = -1 | |
name = None | |
for (k,v) in attrs.items(): | |
if k == "i": | |
i = int(v) | |
elif k == "n": | |
name = v.replace(" ", "_") | |
self.functions[i] = name | |
def process_PF(self, attrs): | |
self.cumulative_metrics.append(defaultdict(int)) | |
self.stack.append((len(self.strings), dict(attrs.items()))) | |
self.strings.append(u"""fl=%s | |
fn=%s | |
""" % (self.files[int(attrs["f"])], self.functions[int(attrs["n"])])) | |
def process_PF_end(self): | |
# Finish current method by a new line | |
self.strings[self.stack[-1][0]] += "\n" | |
called = self.stack.pop() | |
metrics = self.cumulative_metrics.pop() | |
for key in metrics: | |
self.cumulative_metrics[-1][key] += metrics[key] | |
if len(self.stack): | |
self.strings[self.stack[-1][0]] += """cfl=%s | |
cfn=%s | |
calls=1 %s | |
%s %s | |
""" % (self.files[int(called[1]["f"])], self.functions[int(called[1]["n"])], called[1]["l"], self.stack[-1][1]["l"], " ".join((str(metrics[key]) for key in self.metrics_keys))) | |
def process_site(self, attrs): | |
self.cumulative_metrics.append(defaultdict(int)) | |
self.stack.append((self.stack[-1][0], dict(attrs.items()))) | |
def process_site_end(self): | |
self.strings[self.stack[-1][0]] += (self.stack[-1][1]["l"] + " " + " ".join((str(self.cumulative_metrics[-1][key]) for key in self.metrics_keys)) + "\n") | |
self.stack.pop() | |
metrics = self.cumulative_metrics.pop() | |
print metrics | |
for key in metrics: | |
self.cumulative_metrics[-1][key] += metrics[key] | |
def process_call(self, attrs): | |
self.stack.append((self.stack[-1][0], dict(attrs.items()))) | |
def process_call_end(self): | |
self.stack.pop() | |
def dump(self): | |
self.f.writelines(self.strings) | |
if __name__ == "__main__": | |
import sys | |
parser = make_parser() | |
handler = HPCToolKitHandler(open(sys.argv[2],"w")) | |
parser.setContentHandler(handler) | |
parser.parse(open(sys.argv[1],"r")) | |
handler.dump() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment