Skip to content

Commit e671d40

Browse files
committed
Add ddg2dot.py and findblock.py
1 parent 5147971 commit e671d40

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

util/misc/ddg2dot.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/env python3
2+
import argparse
3+
import sys
4+
import re
5+
6+
parser = argparse.ArgumentParser(description='Convert data_dep WriteToFile format to a .dot file')
7+
parser.add_argument('input', help='The WriteToFile format file to convert. Input a single hyphen (-) to read from stdin')
8+
parser.add_argument('-o', '--output', help='The destination to write to. Defaults to stdout')
9+
parser.add_argument('--filter-weights', nargs='*', default=[], help='filter out weights with the respective values')
10+
11+
args = parser.parse_args()
12+
13+
if args.input == '-':
14+
infile = sys.stdin
15+
else:
16+
infile = open(args.input, 'r')
17+
18+
filtered_weights = set(int(x) for x in args.filter_weights)
19+
20+
text = infile.read()
21+
infile.close()
22+
23+
NODE_RE = re.compile(r'node (?P<number>\d+) "(?P<name>.*?)"(\s*"(?P<other_name>.*?)")?')
24+
EDGE_RE = re.compile(r'dep (?P<from>\d+) (?P<to>\d+) "(?P<type>.*?)" (?P<weight>\d+)')
25+
26+
# Holds the resulting strings as a list of the lines.
27+
result = ['digraph G {\n']
28+
29+
# Create the nodes in the graph
30+
for match in NODE_RE.finditer(text):
31+
num = match['number']
32+
name = match['name']
33+
if name == 'artificial': # Prettify entry/exit names
34+
name = ['exit', 'entry'][match['other_name'] == '__optsched_entry']
35+
36+
# Add the node to the graph. Include a node to make it clear what this is
37+
result.append(f' n{num} [label="{name}:n{num}"];\n')
38+
39+
result.append('\n')
40+
41+
# Create the edges in the graph
42+
for match in EDGE_RE.finditer(text):
43+
from_ = match['from']
44+
to = match['to']
45+
type_ = match['type']
46+
weight = match['weight']
47+
48+
# The additional label text if we want to display the weight
49+
# (that is, if the weight is not filtered out)
50+
weight_label = '' if int(weight) in filtered_weights else ':' + weight
51+
# The actual label text
52+
label = weight_label if type_ == 'data' else f'{type_}{weight_label}'
53+
# The dot syntax to produce the actual label
54+
label_section = f'label="{label}"'
55+
56+
attr_section = f' [{label_section}]' if label else ''
57+
# Add the edge
58+
result.append(f' n{from_} -> n{to}{attr_section};\n')
59+
60+
# Graph is now finished:
61+
result.append('}\n')
62+
63+
output = sys.stdout
64+
if args.output: output = open(args.output, 'w')
65+
66+
print(''.join(result), file=output)

util/misc/findblock.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env python3
2+
import sys
3+
import argparse
4+
5+
parser = argparse.ArgumentParser(description='Search spills.dat (from runspec-wrapper) to find the benchmark for a block')
6+
parser.add_argument('spills', help='The spills.dat file to search in. - for stdin')
7+
parser.add_argument('blocks', help='The blocks to search for. This may include the `:##` part, or it may just be the mangled function name', nargs='*')
8+
9+
result = parser.parse_args()
10+
11+
with open(result.spills, 'r') as f:
12+
file = f.read()
13+
14+
fns = (block.split(':')[0] for block in result.blocks)
15+
16+
fn_locs = [file.find(fn) for fn in fns]
17+
fn_benchmarks = [file.rfind(':', 0, fnindex) for fnindex in fn_locs]
18+
fn_benchmark_spans = [(file.rfind('\n', 0, e), e) for e in fn_benchmarks]
19+
fn_benchmarks = [file[b + 1:e] for (b, e) in fn_benchmark_spans]
20+
21+
print('\n'.join(fn_benchmarks))

0 commit comments

Comments
 (0)