-
-
Notifications
You must be signed in to change notification settings - Fork 18.1k
/
vbench_to_asv.py
163 lines (118 loc) · 4.73 KB
/
vbench_to_asv.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
154
155
156
157
158
159
160
161
162
163
import ast
import vbench
import os
import sys
import astor
import glob
def vbench_to_asv_source(bench, kinds=None):
tab = ' ' * 4
if kinds is None:
kinds = ['time']
output = 'class {}(object):\n'.format(bench.name)
output += tab + 'goal_time = 0.2\n\n'
if bench.setup:
indented_setup = [tab * 2 + '{}\n'.format(x) for x in bench.setup.splitlines()]
output += tab + 'def setup(self):\n' + ''.join(indented_setup) + '\n'
for kind in kinds:
output += tab + 'def {}_{}(self):\n'.format(kind, bench.name)
for line in bench.code.splitlines():
output += tab * 2 + line + '\n'
output += '\n\n'
if bench.cleanup:
output += tab + 'def teardown(self):\n' + tab * 2 + bench.cleanup
output += '\n\n'
return output
class AssignToSelf(ast.NodeTransformer):
def __init__(self):
super(AssignToSelf, self).__init__()
self.transforms = {}
self.imports = []
self.in_class_define = False
self.in_setup = False
def visit_ClassDef(self, node):
self.transforms = {}
self.in_class_define = True
functions_to_promote = []
setup_func = None
for class_func in ast.iter_child_nodes(node):
if isinstance(class_func, ast.FunctionDef):
if class_func.name == 'setup':
setup_func = class_func
for anon_func in ast.iter_child_nodes(class_func):
if isinstance(anon_func, ast.FunctionDef):
functions_to_promote.append(anon_func)
if setup_func:
for func in functions_to_promote:
setup_func.body.remove(func)
func.args.args.insert(0, ast.Name(id='self', ctx=ast.Load()))
node.body.append(func)
self.transforms[func.name] = 'self.' + func.name
ast.fix_missing_locations(node)
self.generic_visit(node)
return node
def visit_TryExcept(self, node):
if any(isinstance(x, (ast.Import, ast.ImportFrom)) for x in node.body):
self.imports.append(node)
else:
self.generic_visit(node)
return node
def visit_Assign(self, node):
for target in node.targets:
if isinstance(target, ast.Name) and not isinstance(target.ctx, ast.Param) and not self.in_class_define:
self.transforms[target.id] = 'self.' + target.id
self.generic_visit(node)
return node
def visit_Name(self, node):
new_node = node
if node.id in self.transforms:
if not isinstance(node.ctx, ast.Param):
new_node = ast.Attribute(value=ast.Name(id='self', ctx=node.ctx), attr=node.id, ctx=node.ctx)
self.generic_visit(node)
return ast.copy_location(new_node, node)
def visit_Import(self, node):
self.imports.append(node)
def visit_ImportFrom(self, node):
self.imports.append(node)
def visit_FunctionDef(self, node):
"""Delete functions that are empty due to imports being moved"""
self.in_class_define = False
self.generic_visit(node)
if node.body:
return node
def translate_module(target_module):
g_vars = {}
l_vars = {}
exec('import ' + target_module) in g_vars
print(target_module)
module = eval(target_module, g_vars)
benchmarks = []
for obj_str in dir(module):
obj = getattr(module, obj_str)
if isinstance(obj, vbench.benchmark.Benchmark):
benchmarks.append(obj)
if not benchmarks:
return
rewritten_output = ''
for bench in benchmarks:
rewritten_output += vbench_to_asv_source(bench)
with open('rewrite.py', 'w') as f:
f.write(rewritten_output)
ast_module = ast.parse(rewritten_output)
transformer = AssignToSelf()
transformed_module = transformer.visit(ast_module)
unique_imports = {astor.to_source(node): node for node in transformer.imports}
transformed_module.body = unique_imports.values() + transformed_module.body
transformed_source = astor.to_source(transformed_module)
with open('benchmarks/{}.py'.format(target_module), 'w') as f:
f.write(transformed_source)
if __name__ == '__main__':
cwd = os.getcwd()
new_dir = os.path.join(os.path.dirname(__file__), '../vb_suite')
sys.path.insert(0, new_dir)
for module in glob.glob(os.path.join(new_dir, '*.py')):
mod = os.path.basename(module)
if mod in ['make.py', 'measure_memory_consumption.py', 'perf_HEAD.py', 'run_suite.py', 'test_perf.py', 'generate_rst_files.py', 'test.py', 'suite.py']:
continue
print('')
print(mod)
translate_module(mod.replace('.py', ''))