12
12
# values.
13
13
#
14
14
15
- import gyb , os , os .path , subprocess
15
+ import argparse
16
+ import json
17
+ import os
18
+ import os .path
19
+ import shutil
20
+ import subprocess
21
+ import sys
22
+ import tempfile
23
+ import gyb
24
+
16
25
17
26
def find_which (p ):
18
27
for d in os .environ ["PATH" ].split (os .pathsep ):
19
- full = os .path .join (d ,p )
28
+ full = os .path .join (d , p )
20
29
if os .path .isfile (full ) and os .access (full , os .X_OK ):
21
30
return full
22
31
return p
23
32
33
+
24
34
# Evidently the debug-symbol reader in dtrace is sufficiently slow and/or buggy
25
35
# that attempting to inject probes into a binary w/ debuginfo is asking for a
26
36
# failed run (possibly racing with probe insertion, or probing the stabs
27
37
# entries, see rdar://problem/7037927 or rdar://problem/11490861 respectively),
28
38
# so we sniff the presence of debug symbols here.
29
39
def has_debuginfo (swiftc ):
30
40
swiftc = find_which (swiftc )
31
- for line in subprocess .check_output (["dwarfdump" , "--file-stats" , swiftc ]).splitlines ():
41
+ for line in subprocess .check_output (
42
+ ["dwarfdump" , "--file-stats" , swiftc ]).splitlines ():
32
43
if '%' not in line :
33
44
continue
34
45
fields = line .split ()
@@ -38,20 +49,22 @@ def has_debuginfo(swiftc):
38
49
39
50
40
51
def write_input_file (args , ast , d , n ):
41
- ifile = os .path .join (d , "in%d.swift" % n )
42
- with open (ifile ,'w+' ) as f :
52
+ fname = "in%d.swift" % n
53
+ pathname = os .path .join (d , fname )
54
+ with open (pathname , 'w+' ) as f :
43
55
f .write (gyb .execute_template (ast , '' , N = n ))
44
- return ifile
56
+ return fname
45
57
46
58
47
59
def run_once_with_primary (args , ast , rng , primary_idx ):
48
- import sys , shutil , tempfile , json
49
60
r = {}
50
61
try :
51
- d = tempfile .mkdtemp ()
62
+ if args .tmpdir is not None and not os .path .exists (args .tmpdir ):
63
+ os .makedirs (args .tmpdir , 0700 )
64
+ d = tempfile .mkdtemp (dir = args .tmpdir )
52
65
inputs = [write_input_file (args , ast , d , i ) for i in rng ]
53
66
primary = inputs [primary_idx ]
54
- ofile = os . path . join ( d , "out.o" )
67
+ ofile = "out.o"
55
68
56
69
mode = "-c"
57
70
if args .parse :
@@ -81,31 +94,32 @@ def run_once_with_primary(args, ast, rng, primary_idx):
81
94
print "running: " + " " .join (command )
82
95
83
96
if args .dtrace :
84
- trace = os .path .join (d , "trace.txt" )
85
- script = "pid$target:swiftc:*%s*:entry { @[probefunc] = count() }" % args .select
97
+ trace = "trace.txt"
98
+ script = ("pid$target:swiftc:*%s*:entry { @[probefunc] = count() }"
99
+ % args .select )
86
100
subprocess .check_call (
87
101
["sudo" , "dtrace" , "-q" ,
88
102
"-o" , trace ,
89
103
"-b" , "256" ,
90
104
"-n" , script ,
91
- "-c" , " " .join (command )])
105
+ "-c" , " " .join (command )], cwd = d )
92
106
r = {fields [0 ]: int (fields [1 ]) for fields in
93
- [line .split () for line in open (trace )]
107
+ [line .split () for line in open (os . path . join ( d , trace ) )]
94
108
if len (fields ) == 2 }
95
109
else :
96
110
if args .debug :
97
111
command = ["lldb" , "--" ] + command
98
- stats = os . path . join ( d , "stats.json" )
112
+ stats = "stats.json"
99
113
argv = command + ["-Xllvm" , "-stats" ,
100
114
"-Xllvm" , "-stats-json" ,
101
115
"-Xllvm" , "-info-output-file=" + stats ]
102
- subprocess .check_call (argv )
103
- with open (stats ) as f :
116
+ subprocess .check_call (argv , cwd = d )
117
+ with open (os . path . join ( d , stats ) ) as f :
104
118
r = json .load (f )
105
119
finally :
106
120
shutil .rmtree (d )
107
121
108
- return {k :v for (k ,v ) in r .items () if args .select in k }
122
+ return {k : v for (k , v ) in r .items () if args .select in k }
109
123
110
124
111
125
def run_once (args , ast , rng ):
@@ -122,6 +136,7 @@ def run_once(args, ast, rng):
122
136
else :
123
137
return run_once_with_primary (args , ast , rng , - 1 )
124
138
139
+
125
140
def run_many (args ):
126
141
127
142
if args .dtrace and has_debuginfo (args .swiftc_binary ):
@@ -145,25 +160,24 @@ def run_many(args):
145
160
146
161
147
162
def linear_regression (x , y ):
148
- # By the book: https://en.wikipedia.org/wiki/Simple_linear_regression
149
- n = len (x )
150
- assert n == len (y )
151
- if n == 0 :
152
- return 0 , 0
153
- prod_sum = 0
154
- sum_x = sum (x )
155
- sum_y = sum (y )
156
- sum_prod = sum (a * b for a , b in zip (x , y ))
157
- sum_x_sq = sum (a ** 2 for a in x )
158
- mean_x = sum_x / n
159
- mean_y = sum_y / n
160
- mean_prod = sum_prod / n
161
- mean_x_sq = sum_x_sq / n
162
- covar_xy = mean_prod - mean_x * mean_y
163
- var_x = mean_x_sq - mean_x ** 2
164
- slope = covar_xy / var_x
165
- inter = mean_y - slope * mean_x
166
- return slope , inter
163
+ # By the book: https://en.wikipedia.org/wiki/Simple_linear_regression
164
+ n = len (x )
165
+ assert n == len (y )
166
+ if n == 0 :
167
+ return 0 , 0
168
+ sum_x = sum (x )
169
+ sum_y = sum (y )
170
+ sum_prod = sum (a * b for a , b in zip (x , y ))
171
+ sum_x_sq = sum (a ** 2 for a in x )
172
+ mean_x = sum_x / n
173
+ mean_y = sum_y / n
174
+ mean_prod = sum_prod / n
175
+ mean_x_sq = sum_x_sq / n
176
+ covar_xy = mean_prod - mean_x * mean_y
177
+ var_x = mean_x_sq - mean_x ** 2
178
+ slope = covar_xy / var_x
179
+ inter = mean_y - slope * mean_x
180
+ return slope , inter
167
181
168
182
169
183
def report (args , rng , runs ):
@@ -196,7 +210,6 @@ def report(args, rng, runs):
196
210
197
211
198
212
def main ():
199
- import argparse , sys
200
213
parser = argparse .ArgumentParser ()
201
214
parser .add_argument (
202
215
'file' , type = argparse .FileType (),
@@ -241,9 +254,12 @@ def main():
241
254
parser .add_argument (
242
255
'--swiftc-binary' ,
243
256
default = "swiftc" , help = 'swift binary to execute' )
257
+ parser .add_argument (
258
+ '--tmpdir' , type = str ,
259
+ default = None , help = 'directory to create tempfiles in' )
244
260
parser .add_argument (
245
261
'--select' ,
246
- default = "" , help = 'substring of counters/symbols to restrict attention to' )
262
+ default = "" , help = 'substring of counters/symbols to limit attention to' )
247
263
parser .add_argument (
248
264
'--debug' , action = 'store_true' ,
249
265
default = False , help = 'invoke lldb on each scale test' )
@@ -273,5 +289,6 @@ def main():
273
289
exit (1 )
274
290
exit (0 )
275
291
292
+
276
293
if __name__ == '__main__' :
277
294
main ()
0 commit comments