23
23
import re
24
24
25
25
26
- class JobStats (object ):
27
- """Object holding the stats of a single job run during a compilation,
28
- corresponding to a single JSON file produced by a single job process
29
- passed -stats-output-dir."""
26
+ class JobData (object ):
30
27
31
- def __init__ (self , jobkind , jobid , module , start_usec , dur_usec ,
32
- jobargs , stats ):
28
+ def __init__ (self , jobkind , jobid , module , jobargs ):
33
29
self .jobkind = jobkind
34
30
self .jobid = jobid
35
31
self .module = module
36
- self .start_usec = start_usec
37
- self .dur_usec = dur_usec
38
32
self .jobargs = jobargs
39
- self .stats = stats
33
+ ( self .input , self . triple , self . out , self . opt ) = jobargs [ 0 : 4 ]
40
34
41
35
def is_driver_job (self ):
42
36
"""Return true iff self measures a driver job"""
@@ -46,6 +40,29 @@ def is_frontend_job(self):
46
40
"""Return true iff self measures a frontend job"""
47
41
return self .jobkind == 'frontend'
48
42
43
+
44
+ class JobProfs (JobData ):
45
+ """Object denoting the profile of a single job run during a compilation,
46
+ corresponding to a single directory of profiles produced by a single
47
+ job process passed -stats-output-dir."""
48
+
49
+ def __init__ (self , jobkind , jobid , module , jobargs , profiles ):
50
+ self .profiles = profiles
51
+ super (JobProfs , self ).__init__ (jobkind , jobid , module , jobargs )
52
+
53
+
54
+ class JobStats (JobData ):
55
+ """Object holding the stats of a single job run during a compilation,
56
+ corresponding to a single JSON file produced by a single job process
57
+ passed -stats-output-dir."""
58
+
59
+ def __init__ (self , jobkind , jobid , module , start_usec , dur_usec ,
60
+ jobargs , stats ):
61
+ self .start_usec = start_usec
62
+ self .dur_usec = dur_usec
63
+ self .stats = stats
64
+ super (JobStats , self ).__init__ (jobkind , jobid , module , jobargs )
65
+
49
66
def driver_jobs_ran (self ):
50
67
"""Return the count of a driver job's ran sub-jobs"""
51
68
assert (self .is_driver_job ())
@@ -190,6 +207,11 @@ def to_lnt_test_obj(self, args):
190
207
r"-(?P<pid>\d+)(-.*)?.json$" )
191
208
FILEPAT = re .compile (FILEPATSTR )
192
209
210
+ PROFILEPATSTR = (r"^profile-(?P<start>\d+)-swift-(?P<kind>\w+)-" +
211
+ AUXPATSTR +
212
+ r"-(?P<pid>\d+)(-.*)?.dir$" )
213
+ PROFILEPAT = re .compile (PROFILEPATSTR )
214
+
193
215
194
216
def match_auxpat (s ):
195
217
m = AUXPAT .match (s )
@@ -215,6 +237,64 @@ def match_filepat(s):
215
237
return None
216
238
217
239
240
+ def match_profilepat (s ):
241
+ m = PROFILEPAT .match (s )
242
+ if m is not None :
243
+ return m .groupdict ()
244
+ else :
245
+ return None
246
+
247
+
248
+ def find_profiles_in (profiledir , select_stat = []):
249
+ sre = re .compile ('.*' if len (select_stat ) == 0 else
250
+ '|' .join (select_stat ))
251
+ profiles = None
252
+ for profile in os .listdir (profiledir ):
253
+ if profile .endswith (".svg" ):
254
+ continue
255
+ if sre .search (profile ) is None :
256
+ continue
257
+ fullpath = os .path .join (profiledir , profile )
258
+ s = os .stat (fullpath )
259
+ if s .st_size != 0 :
260
+ if profiles is None :
261
+ profiles = dict ()
262
+ try :
263
+ (counter , profiletype ) = os .path .splitext (profile )
264
+ # drop leading period from extension
265
+ profiletype = profiletype [1 :]
266
+ if profiletype not in profiles :
267
+ profiles [profiletype ] = dict ()
268
+ profiles [profiletype ][counter ] = fullpath
269
+ except :
270
+ pass
271
+ return profiles
272
+
273
+
274
+ def list_stats_dir_profiles (path , select_module = [], select_stat = [], ** kwargs ):
275
+ """Finds all stats-profiles in path, returning list of JobProfs objects"""
276
+ jobprofs = []
277
+ for root , dirs , files in os .walk (path ):
278
+ for d in dirs :
279
+ mg = match_profilepat (d )
280
+ if not mg :
281
+ continue
282
+ # NB: "pid" in fpat is a random number, not unix pid.
283
+ jobkind = mg ['kind' ]
284
+ jobid = int (mg ['pid' ])
285
+ module = mg ["module" ]
286
+ if len (select_module ) != 0 and module not in select_module :
287
+ continue
288
+ jobargs = [mg ["input" ], mg ["triple" ], mg ["out" ], mg ["opt" ]]
289
+
290
+ e = JobProfs (jobkind = jobkind , jobid = jobid ,
291
+ module = module , jobargs = jobargs ,
292
+ profiles = find_profiles_in (os .path .join (root , d ),
293
+ select_stat ))
294
+ jobprofs .append (e )
295
+ return jobprofs
296
+
297
+
218
298
def load_stats_dir (path , select_module = [], select_stat = [],
219
299
exclude_timers = False , merge_timers = False , ** kwargs ):
220
300
"""Loads all stats-files found in path into a list of JobStats objects"""
0 commit comments