pwrake 0.9.5 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,355 @@
1
+ module Pwrake
2
+
3
+ class Report
4
+
5
+ HTML_HEAD = <<EOL
6
+ <html><head><style>
7
+ <!--
8
+ h2 {
9
+ background-color:#eee;
10
+ }
11
+ h1 {
12
+ background-color:#0ff;
13
+ }
14
+ table {
15
+ margin:0px;
16
+ border-style:solid;
17
+ border-width:1px;
18
+ }
19
+ td {
20
+ margin:0px;
21
+ border-style:solid;
22
+ border-width:1px;
23
+ }
24
+ -->
25
+ </style>
26
+ </head>
27
+ <body>
28
+ EOL
29
+
30
+ @@id = 0
31
+ @@id_fmt = nil
32
+
33
+ def initialize(base,pattern)
34
+ @base = base
35
+ @pattern = pattern
36
+
37
+ @@id = @@id.succ
38
+ @id = @@id
39
+
40
+ @csv_file = base+'.csv'
41
+ @task_file = base+'.task'
42
+ @html_file = base+'.html'
43
+
44
+ open(@base+".log","r").each do |s|
45
+ if /num_cores=(\d+)/ =~ s
46
+ @ncore = $1.to_i
47
+ break
48
+ end
49
+ end
50
+
51
+ @sh_table = CSV.read(@csv_file,:headers=>true)
52
+ h = {}
53
+ @sh_table.each do |row|
54
+ if host = row['host']
55
+ h[host] = true
56
+ end
57
+ end
58
+ @hosts = h.keys.sort
59
+ @start_time = Time.parse(@sh_table[0]["start_time"])
60
+ @end_time = Time.parse(@sh_table[-1]["start_time"])
61
+ @elap = @end_time - @start_time
62
+ read_elap_each_cmd
63
+ make_cmd_stat
64
+ end
65
+
66
+ attr_reader :base, :ncore, :elap
67
+ attr_reader :csv_file, :html_file
68
+ attr_reader :cmd_elap, :cmd_stat
69
+ attr_reader :sh_table, :task_table
70
+ attr_reader :id
71
+
72
+ def id_str
73
+ if @@id_fmt.nil?
74
+ id_len = Math.log10(@@id).floor + 1
75
+ @@id_fmt = "#%0#{id_len}d"
76
+ end
77
+ @@id_fmt % @id
78
+ end
79
+
80
+ def read_elap_each_cmd
81
+ @cmd_elap = {}
82
+ @sh_table.each do |row|
83
+ command = row['command']
84
+ elap = row['elap_time']
85
+ if command && elap
86
+ elap = elap.to_f
87
+ found = nil
88
+ @pattern.each do |cmd,regex|
89
+ if regex =~ command
90
+ if a = @cmd_elap[cmd]
91
+ a << elap
92
+ else
93
+ @cmd_elap[cmd] = [elap]
94
+ end
95
+ found = true
96
+ end
97
+ end
98
+ if !found
99
+ if cmd = get_command( command )
100
+ if a = @cmd_elap[cmd]
101
+ a << elap
102
+ else
103
+ @cmd_elap[cmd] = [elap]
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ @cmd_elap
110
+ end
111
+
112
+ def get_command(s)
113
+ if /\(([^()]+)\)/ =~ s
114
+ s = $1
115
+ end
116
+ a = s.split(/;/)
117
+ a.each do |x|
118
+ if /^\s*(\S+)/ =~ x
119
+ k = $1
120
+ next if k=='cd'
121
+ return k
122
+ end
123
+ end
124
+ nil
125
+ end
126
+
127
+ def make_cmd_stat
128
+ @cmd_stat = {}
129
+ @cmd_elap.each do |cmd,elap|
130
+ @cmd_stat[cmd] = s = Stat.new(elap)
131
+ if elap.size > 1
132
+ s.make_logx_histogram(1.0/8)
133
+ end
134
+ end
135
+ end
136
+
137
+ def format_comma(x)
138
+ x.to_s.gsub(/(?<=\d)(?=(?:\d\d\d)+(?!\d))/, ',')
139
+ end
140
+
141
+ def tr_count(x,y)
142
+ sum = x+y
143
+ td = "<td align='right' valign='top'>"
144
+ m = td + "%s<br/>%.2f%%</td>" % [format_comma(x),x*100.0/sum]
145
+ m << td + "%s<br/>%.2f%%</td>" % [format_comma(y),y*100.0/sum]
146
+ m << td + "%s</td>" % format_comma(sum)
147
+ m
148
+ end
149
+
150
+ def report_html
151
+ html = HTML_HEAD + "<body><h1>Pwrake Statistics</h1>\n"
152
+ html << "<h2>Workflow</h2>\n"
153
+ html << "<table>\n"
154
+ html << "<tr><th>log file</th><td>#{@base}</td><tr>\n"
155
+ html << "<tr><th>ncore</th><td>#{@ncore}</td><tr>\n"
156
+ html << "<tr><th>elapsed time(sec)</th><td>#{@elap}</td><tr>\n"
157
+ html << "<tr><th>start time</th><td>#{@start_time}</td><tr>\n"
158
+ html << "<tr><th>end time</th><td>#{@end_time}</td><tr>\n"
159
+ html << "</table>\n"
160
+ html << "<table>\n"
161
+ html << "<tr><th>hosts</th><tr>\n"
162
+ @hosts.each do |h|
163
+ html << "<tr><td>#{h}</td><tr>\n"
164
+ end
165
+ html << "</table>\n"
166
+ html << "<h2>Parallelism</h2>\n"
167
+ fimg = Parallelism.plot_parallelism2(@csv_file)
168
+ html << "<img src='#{fimg}' align='top'/></br>\n"
169
+
170
+ html << "<h2>Parallelism by host</h2>\n"
171
+ fimg2 = Parallelism.plot_parallelizm_by_host(@sh_table,@base)
172
+ html << "<img src='#{fimg2}' align='top'/></br>\n"
173
+
174
+ html << "<h2>Command statistics</h2>\n"
175
+ html << "<table>\n"
176
+ html << "<tr><th>command</th>"
177
+ html << Stat.html_th
178
+ html << "</tr>\n"
179
+ @cmd_stat.each do |cmd,stat|
180
+ html << "<tr><td>#{cmd}</td>"
181
+ html << stat.html_td
182
+ html << "</tr>\n"
183
+ end
184
+ html << "<table>\n"
185
+ html << "<img src='#{histogram_plot}' align='top'/></br>\n"
186
+
187
+ task_locality
188
+ html << "<h2>Locality statistics</h2>\n"
189
+ html << "<table>\n"
190
+
191
+ html << "<tr><th></th><th rowspan=3>gross elapsed time (sec)</th><th></th>"
192
+ html << "<th colspan=6>read</th>"
193
+ html << "<th></th>"
194
+ html << "<th colspan=6>write</th>"
195
+ html << "</tr>\n"
196
+
197
+
198
+ html << "<tr><th></th><th></th>"
199
+ html << "<th colspan=3>count</th><th colspan=3>file size (bytes)</th>"
200
+ html << "<th></th>"
201
+ html << "<th colspan=3>count</th><th colspan=3>file size (bytes)</th>"
202
+ html << "</tr>\n"
203
+
204
+ html << "<tr><th>host</th><th></th>"
205
+ html << "<th>local</th><th>remote</th><th>total</th>"
206
+ html << "<th>local</th><th>remote</th><th>total</th>"
207
+ html << "<th></th>"
208
+ html << "<th>local</th><th>remote</th><th>total</th>"
209
+ html << "<th>local</th><th>remote</th><th>total</th>"
210
+ html << "</tr>\n"
211
+ n_same_input = 0
212
+ size_same_input = 0
213
+ n_diff_input = 0
214
+ size_diff_input = 0
215
+ n_same_output = 0
216
+ size_same_output = 0
217
+ n_diff_output = 0
218
+ size_diff_output = 0
219
+ elap_host = 0
220
+ @exec_hosts.each do |h|
221
+ html << "<tr><td>#{h}</td>"
222
+ html << "<td align='right'>%.3f</td>" % @elap_host[h]
223
+ html << "<td></td>"
224
+ html << tr_count(@n_same_input[h],@n_diff_input[h])
225
+ html << tr_count(@size_same_input[h],@size_diff_input[h])
226
+ html << "<td></td>"
227
+ html << tr_count(@n_same_output[h],@n_diff_output[h])
228
+ html << tr_count(@size_same_output[h],@size_diff_output[h])
229
+
230
+ html << "</tr>\n"
231
+ n_same_input += @n_same_input[h]
232
+ size_same_input += @size_same_input[h]
233
+ n_diff_input += @n_diff_input[h]
234
+ size_diff_input += @size_diff_input[h]
235
+ n_same_output += @n_same_output[h]
236
+ size_same_output += @size_same_output[h]
237
+ n_diff_output += @n_diff_output[h]
238
+ size_diff_output += @size_diff_output[h]
239
+ elap_host += @elap_host[h]
240
+ end
241
+ html << "<tr><td>total</td>"
242
+ html << "<td align='right'>%.3f</td>" % elap_host
243
+ html << "<td></td>"
244
+ html << tr_count(n_same_input,n_diff_input)
245
+ html << tr_count(size_same_input,size_diff_input)
246
+ html << "<td></td>"
247
+ html << tr_count(n_same_output,n_diff_output)
248
+ html << tr_count(size_same_output,size_diff_output)
249
+
250
+ html << "</tr>\n"
251
+ html << "<table>\n"
252
+
253
+ html << "</body></html>\n"
254
+ File.open(@html_file,"w") do |f|
255
+ f.puts html
256
+ end
257
+ puts "generate "+@html_file
258
+ end
259
+
260
+ def task_locality
261
+ @task_table = CSV.read(@task_file,:headers=>true)
262
+ file_size = {}
263
+ file_host = {}
264
+ @task_table.each do |row|
265
+ name = row['task_name']
266
+ file_size[name] = row['file_size'].to_i
267
+ file_host[name] = (row['file_host']||'').split('|')
268
+ end
269
+
270
+ @n_same_output = Hash.new(0)
271
+ @size_same_output= Hash.new(0)
272
+ @n_diff_output = Hash.new(0)
273
+ @size_diff_output= Hash.new(0)
274
+ @n_same_input = Hash.new(0)
275
+ @size_same_input = Hash.new(0)
276
+ @n_diff_input = Hash.new(0)
277
+ @size_diff_input = Hash.new(0)
278
+ h = {}
279
+ @task_table.each do |row|
280
+ if row['executed']=='1'
281
+ name = row['task_name']
282
+ exec_host = row['exec_host']
283
+ h[exec_host] = true
284
+ if file_host[name].include?(exec_host)
285
+ @n_same_output[exec_host] += 1
286
+ @size_same_output[exec_host] += file_size[name]
287
+ else
288
+ @n_diff_output[exec_host] += 1
289
+ @size_diff_output[exec_host] += file_size[name]
290
+ end
291
+ preq_files = (row['preq']||'').split('|')
292
+ preq_files.each do |preq|
293
+ if (sz=file_size[preq]) && sz > 0
294
+ if file_host[preq].include?(exec_host)
295
+ @n_same_input[exec_host] += 1
296
+ @size_same_input[exec_host] += sz
297
+ else
298
+ @n_diff_input[exec_host] += 1
299
+ @size_diff_input[exec_host] += sz
300
+ end
301
+ end
302
+ end
303
+ end
304
+ end
305
+ @exec_hosts = h.keys.sort
306
+
307
+ @elap_host = Hash.new(0)
308
+ @sh_table.each do |row|
309
+ if (h = row['host']) && (t = row['elap_time'])
310
+ @elap_host[h] += t.to_f
311
+ end
312
+ end
313
+ end
314
+
315
+ def histogram_plot
316
+ command_list = []
317
+ @cmd_stat.each do |cmd,stat|
318
+ if stat.n > 2
319
+ command_list << cmd
320
+ end
321
+ end
322
+ hist_image = @base+"_hist.png"
323
+ IO.popen("gnuplot","r+") do |f|
324
+ f.puts "
325
+ set terminal png # size 480,360
326
+ set output '#{hist_image}'
327
+ set ylabel 'histogram'
328
+ set xlabel 'Execution time (sec)'
329
+ set logscale x
330
+ set title 'histogram of elapsed time'"
331
+ a = []
332
+
333
+ command_list.each_with_index do |n,i|
334
+ a << "'-' w histeps ls #{i+1} title ''"
335
+ a << "'-' w lines ls #{i+1} title '#{n}'"
336
+ end
337
+ f.puts "plot "+ a.join(',')
338
+
339
+ command_list.each do |cmd|
340
+ stat = @cmd_stat[cmd]
341
+ 2.times do
342
+ stat.hist_each do |x1,x2,y|
343
+ x = Math.sqrt(x1*x2)
344
+ f.printf "%f %d\n", x, y
345
+ end
346
+ f.puts "e"
347
+ end
348
+ end
349
+ hist_image
350
+ end
351
+ end
352
+
353
+
354
+ end
355
+ end
@@ -0,0 +1,196 @@
1
+ module Pwrake
2
+
3
+ class ReportMulti
4
+
5
+ def initialize(list,pattern)
6
+ @reports = list.map do |base|
7
+ r = Report.new(base,pattern)
8
+ puts r.base+" elap=#{r.elap}"
9
+ r
10
+ end
11
+ @pattern = pattern
12
+ @elap_png = 'elap.png'
13
+ end
14
+
15
+ def report(stat_html)
16
+ if true
17
+ @reports.each do |r|
18
+ r.report_html
19
+ end
20
+ plot_elap
21
+ end
22
+ html = Report::HTML_HEAD + "<body><h1>Pwrake Statistics</h1>\n"
23
+ html << "<h2>Log files</h2>\n"
24
+ html << "<table>\n"
25
+ html << "<tr><th>log file</th><th>id</th><th>ncore</th><th>elapsed time(sec)</th><tr>\n"
26
+ @reports.each do |r|
27
+ html << "<tr><td><a href='#{r.html_file}'>#{r.base}</a></td>"
28
+ html << "<td>#{r.id_str}</td><td>#{r.ncore}</td><td>#{r.elap}</td><tr>\n"
29
+ end
30
+ html << "</table>\n"
31
+ html << "<h2>Elapsed time</h2>\n"
32
+ html << "<img src='#{@elap_png}' align='top'/></br>\n"
33
+
34
+ html << "<h2>Histogram of Execution time</h2>\n"
35
+ html << report_histogram()
36
+ html << "</body></html>\n"
37
+
38
+ File.open(stat_html,"w") do |f|
39
+ f.puts html
40
+ end
41
+ end
42
+
43
+ def plot_elap
44
+ a = @reports.map{|r| r.ncore * r.elap}.min
45
+ elaps = @reports.map{|r| r.elap}
46
+ logmin = Math.log10(elaps.min)
47
+ logmax = Math.log10(elaps.max)
48
+ mid = (logmin+logmax)/2
49
+ wid = (logmax-logmin).ceil*0.5
50
+ ymin = 10**(mid-wid)
51
+ ymax = 10**(mid+wid)
52
+ IO.popen("gnuplot","r+") do |f|
53
+ f.puts "
54
+ set terminal png size 640,480
55
+ set output '#{@elap_png}'
56
+ set xlabel 'ncore'
57
+ set ylabel 'time (sec)'
58
+ set yrange [#{ymin}:#{ymax}]
59
+ set logscale xy
60
+ plot #{a}/x,'-' w lp lw 2 ps 2 title 'elapsed time'
61
+ "
62
+ @reports.sort_by{|r| r.ncore}.each do |r|
63
+ f.puts "#{r.ncore} #{r.elap}"
64
+ end
65
+ f.puts "e"
66
+ end
67
+ puts "Ncore-time plot: "+@elap_png
68
+ end
69
+
70
+ def report_histogram
71
+ @images = {}
72
+ @cmd_rep = {}
73
+
74
+ @reports.each do |r|
75
+ r.cmd_stat.each do |cmd,stat|
76
+ if stat.n > 2
77
+ @cmd_rep[cmd] ||= {}
78
+ @cmd_rep[cmd][r.id_str] = r # stat
79
+ end
80
+ end
81
+ end
82
+
83
+ @cmd_rep.each_key do |cmd|
84
+ @images[cmd] = 'hist_'+cmd.gsub(/[\/.]/,'_')+'.png'
85
+ end
86
+ histogram_plot
87
+ histogram_html
88
+ end
89
+
90
+ def histogram_html
91
+ html = ""
92
+ @cmd_rep.each do |cmd,cmd_rep|
93
+ html << "<p>Statistics of Elapsed time of #{cmd}</p>\n<table>\n"
94
+ html << "<th>id</th><th>ncore</th>"+Stat.html_th
95
+ cmd_rep.each do |id,r|
96
+ s = r.cmd_stat[cmd]
97
+ html << "<tr><td>#{id}</td><td>#{r.ncore}</td>" + s.html_td + "</tr>\n"
98
+ end
99
+ html << "</table>\n"
100
+ html << "<img src='./#{@images[cmd]}'/>\n"
101
+ end
102
+ html
103
+ end
104
+
105
+ def histogram_plot
106
+ @cmd_rep.each do |cmd,cmd_rep|
107
+ IO.popen("gnuplot","r+") do |f|
108
+ f.puts "
109
+ set terminal png # size 480,360
110
+ set output '#{@images[cmd]}'
111
+ set ylabel 'histogram'
112
+ set xlabel 'Execution time (sec)'
113
+ set logscale x
114
+ set title '#{cmd}'"
115
+ a = []
116
+ ncores = cmd_rep.keys
117
+ ncores.each_with_index{|n,i|
118
+ a << "'-' w histeps ls #{i+1} title ''"
119
+ a << "'-' w lines ls #{i+1} title '#{n}'"
120
+ }
121
+ f.puts "plot "+ a.join(',')
122
+
123
+ cmd_rep.each do |ncore,r|
124
+ s = r.cmd_stat[cmd]
125
+ 2.times do
126
+ s.hist_each do |x1,x2,y|
127
+ x = Math.sqrt(x1*x2)
128
+ f.printf "%f %d\n", x, y
129
+ end
130
+ f.puts "e"
131
+ end
132
+ end
133
+ end
134
+ puts "Histogram plot: #{@images[cmd]}"
135
+ end
136
+ end
137
+
138
+ def histogram_plot2
139
+ @cmd_rep.each do |cmd,cmd_rep|
140
+ IO.popen("gnuplot","r+") do |f|
141
+ f.puts "
142
+ set terminal png # size 480,360
143
+ set output '#{@images[cmd]}'
144
+ set nohidden3d
145
+ set palette rgb 33,13,10
146
+ set pm3d
147
+ set ticslevel 0
148
+ unset colorbox
149
+ set yrange [#{cmd_rep.size}:0]
150
+ set logscale x
151
+ set title '#{cmd}'"
152
+ a = []
153
+ ncores = cmd_rep.keys.sort
154
+ ncores.each_with_index{|n,i|
155
+ a << "'-' w lines ls #{i+1} title '#{n} cores'"
156
+ }
157
+ f.puts "splot "+ a.join(',')
158
+
159
+ ncores.each_with_index do |ncore,i|
160
+ s = cmd_rep[ncore]
161
+ y = i
162
+ s.hist_each do |x1,x2,z|
163
+ f.printf "%g %g 0\n", x1,y
164
+ f.printf "%g %g 0\n", x2,y
165
+ f.printf "%g %g 0\n", x2,y
166
+ end
167
+ f.puts ""
168
+ s.hist_each do |x1,x2,z|
169
+ f.printf "%g %g %g\n", x1,y,z
170
+ f.printf "%g %g %g\n", x2,y,z
171
+ f.printf "%g %g 0\n", x2,y,z
172
+ end
173
+ f.puts ""
174
+ y = i+1
175
+ s.hist_each do |x1,x2,z|
176
+ f.printf "%g %g %g\n", x1,y,z
177
+ f.printf "%g %g %g\n", x2,y,z
178
+ f.printf "%g %g 0\n", x2,y,z
179
+ end
180
+ f.puts ""
181
+ s.hist_each do |x1,x2,z|
182
+ f.printf "%g %g 0\n", x1,y
183
+ f.printf "%g %g 0\n", x2,y
184
+ f.printf "%g %g 0\n", x2,y
185
+ end
186
+ f.puts "e"
187
+ i = i+1
188
+ end
189
+ end
190
+ puts "Histogram plot: #{@images[cmd]}"
191
+ end
192
+ end
193
+
194
+ end
195
+ end
196
+
@@ -0,0 +1,115 @@
1
+ module Pwrake
2
+
3
+ class Stat
4
+
5
+ def initialize(data)
6
+ @data = data
7
+ @n = data.size
8
+ if @n>0
9
+ @min = data.min
10
+ @max = data.max
11
+ @sum = data.inject(0){|s,x| s+x}
12
+ @mean = @sum/@n
13
+ @median = _median
14
+ @mean_absolute_deviation = data.inject(0){|s,x| (x-@mean).abs} / @n
15
+ if @n>1
16
+ @variance = data.inject(0){|s,x| y=x-@mean; y**2} / (@n-1)
17
+ @sdev = Math.sqrt(@variance)
18
+ @skew = data.inject(0){|s,x| y=(x-@mean)/@sdev; y**3} / @n
19
+ @kurt = data.inject(0){|s,x| y=(x-@mean)/@sdev; y**4} / @n - 3
20
+ end
21
+ end
22
+ end
23
+
24
+ attr_reader :n
25
+ attr_reader :min, :max, :sum, :mean, :median
26
+ attr_reader :mean_absolute_deviation
27
+ attr_reader :variance, :sdev, :skew, :kurt
28
+ attr_reader :hist, :hist_min, :hist_max, :bin
29
+
30
+ def make_logx_histogram(bin)
31
+ @bin = bin # 1.0/10
32
+ @i_max = (Math.log10(@max)/@bin).floor
33
+ @i_min = (Math.log10(@min)/@bin).floor
34
+ @hist_min = 10**(@i_min * @bin)
35
+ @hist_max = 10**((@i_max+1) * @bin)
36
+ @hist = Array.new(@i_max-@i_min+1,0)
37
+ @data.each do |x|
38
+ i = (Math.log10(x)/@bin-@i_min).floor
39
+ raise "invalid index i=#{i}" if i<0 || i>@i_max-@i_min
40
+ @hist[i] += 1
41
+ end
42
+ end
43
+
44
+ def hist_each
45
+ if @hist
46
+ n = @hist.size
47
+ n.times do |i|
48
+ x1 = 10**(@bin*(i+@i_min))
49
+ x2 = 10**(@bin*(i+1+@i_min))
50
+ y = @hist[i]
51
+ yield x1,x2,y
52
+ end
53
+ end
54
+ end
55
+
56
+ def _median
57
+ if @n==1
58
+ @data[0]
59
+ elsif @n==2
60
+ @mean
61
+ else
62
+ case @n%2
63
+ when 1
64
+ i = (@n-1)/2
65
+ @data.sort[i]
66
+ else
67
+ i = @n/2
68
+ s = @data.sort
69
+ (s[i]+s[i+1])/2
70
+ end
71
+ end
72
+ end
73
+
74
+ def report
75
+ case @n
76
+ when 0
77
+ "no data"
78
+ when 1
79
+ "n=1 mean=%g"%@mean
80
+ else
81
+ "n=%i mean=%g median=%g min=%g max=%g sdev=%g skew=%g kurt=%g" %
82
+ [@n, @mean, @median, @min, @max, @sdev||0, @skew||0, @kurt||0]
83
+ "n=%i mean=%g median=%g min=%g max=%g sdev=%g" %
84
+ [@n, @mean, @median, @min, @max, @sdev||0]
85
+ end
86
+ end
87
+
88
+ def stat_array
89
+ [@n, @mean, @median, @min, @max, @sdev||0]
90
+ end
91
+
92
+ def html_td
93
+ "<td>%i</td><td>%g</td><td>%g</td><td>%g</td><td>%g</td><td>%g</td>" %
94
+ [@n, @mean, @median, @min, @max, @sdev||0]
95
+ end
96
+
97
+ def self.html_th
98
+ "<th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th>" %
99
+ %w[n mean median min max sdev]
100
+ end
101
+
102
+ def report2
103
+ case @n
104
+ when 0
105
+ " no data"
106
+ when 1
107
+ " n=1\n mean=%g"%@mean
108
+ else
109
+ " n=%i\n mean=%g\n median=%g\n min=%g\n max=%g\n sdev=%g\n skew=%g\n kurt=%g" %
110
+ [@n, @mean, @median, @min, @max, @sdev||0, @skew||0, @kurt||0]
111
+ end
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1,6 @@
1
+ require 'time'
2
+ require 'csv'
3
+ require 'pwrake/report/parallelism.rb'
4
+ require 'pwrake/report/report.rb'
5
+ require 'pwrake/report/report_multi.rb'
6
+ require 'pwrake/report/stat.rb'