Last active
August 29, 2015 14:24
-
-
Save mbrucher/6cad31e38beca770523b to your computer and use it in GitHub Desktop.
Script to convert from XML HPCToolkit format to callgrind
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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