pwrake 2.2.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/pwrake +2 -0
- data/lib/pwrake/branch/communicator_set.rb +1 -1
- data/lib/pwrake/branch/shell.rb +2 -6
- data/lib/pwrake/branch/shell_profiler.rb +4 -3
- data/lib/pwrake/master/master.rb +13 -8
- data/lib/pwrake/master/master_application.rb +4 -0
- data/lib/pwrake/mpi/branch.rb +1 -0
- data/lib/pwrake/queue/queue_array.rb +9 -9
- data/lib/pwrake/queue/task_queue.rb +15 -15
- data/lib/pwrake/report/parallelism.rb +74 -84
- data/lib/pwrake/report/report.rb +36 -12
- data/lib/pwrake/task/task_algorithm.rb +32 -21
- data/lib/pwrake/task/task_wrapper.rb +9 -9
- data/lib/pwrake/version.rb +1 -1
- data/lib/pwrake/worker/executor.rb +38 -1
- data/lib/pwrake/worker/invoker.rb +21 -6
- data/lib/pwrake/worker/writer.rb +20 -24
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 165b50b8450d65b495aefffe22cc3a8e02ae3828
|
4
|
+
data.tar.gz: 210a2fcb2b42cb1b70696e84595e20dd71332c83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce57a49375d39fc42a4a785bb9e703fe4f90af8f5ec2db63c4a1d5fb7beb3c3d3f44b37742a1cbb8c9f40621cbc3d66a8c458cb17a6d530d9ad43374bda829e9
|
7
|
+
data.tar.gz: fae5ad1e68b9b7f87ab12428e9826a50ed8809120c2f4a5a45215518ff7e590f82051d6e4fb7e63914222b81c6dbea762c8ef7cfaf8e88a4823f6e176d325df0
|
data/bin/pwrake
CHANGED
@@ -15,6 +15,7 @@ require "pwrake/master/master_application"
|
|
15
15
|
require "pwrake/task/task_manager"
|
16
16
|
require "pwrake/task/task_algorithm"
|
17
17
|
require "pwrake/branch/branch_application"
|
18
|
+
|
18
19
|
class Rake::Application
|
19
20
|
include Pwrake::BranchApplication
|
20
21
|
prepend Pwrake::MasterApplication
|
@@ -22,6 +23,7 @@ class Rake::Application
|
|
22
23
|
end
|
23
24
|
class Rake::Task
|
24
25
|
include Pwrake::TaskAlgorithm
|
26
|
+
prepend Pwrake::TaskInvoke
|
25
27
|
end
|
26
28
|
|
27
29
|
# does NOT exit when writing to broken pipe
|
data/lib/pwrake/branch/shell.rb
CHANGED
@@ -72,11 +72,6 @@ module Pwrake
|
|
72
72
|
false
|
73
73
|
end
|
74
74
|
|
75
|
-
def set_current_task(task_id,task_name)
|
76
|
-
@task_id = task_id
|
77
|
-
@task_name = task_name
|
78
|
-
end
|
79
|
-
|
80
75
|
def backquote(*command)
|
81
76
|
command = command.join(' ')
|
82
77
|
@lock.synchronize do
|
@@ -156,7 +151,7 @@ module Pwrake
|
|
156
151
|
ensure
|
157
152
|
end_time = Time.now
|
158
153
|
@status = @@profiler.profile(@task_id, @task_name, cmd,
|
159
|
-
|
154
|
+
start_time, end_time, host, @ncore, @status)
|
160
155
|
end
|
161
156
|
end
|
162
157
|
|
@@ -232,6 +227,7 @@ module Pwrake
|
|
232
227
|
@task_id = task_id
|
233
228
|
@task_name = task_name
|
234
229
|
task = Rake.application[task_name]
|
230
|
+
@ncore = task.wrapper.n_used_cores
|
235
231
|
begin
|
236
232
|
task.execute(task.arguments) if task.needed?
|
237
233
|
result = "taskend:#{@id}:#{task.name}"
|
@@ -6,7 +6,7 @@ module Pwrake
|
|
6
6
|
|
7
7
|
HEADER_FOR_PROFILE =
|
8
8
|
%w[exec_id task_id task_name command
|
9
|
-
start_time end_time elap_time host status]
|
9
|
+
start_time end_time elap_time host ncore status]
|
10
10
|
|
11
11
|
HEADER_FOR_GNU_TIME =
|
12
12
|
%w[realtime systime usrtime maxrss averss memsz
|
@@ -85,7 +85,8 @@ module Pwrake
|
|
85
85
|
t.strftime("%F %T.%L")
|
86
86
|
end
|
87
87
|
|
88
|
-
def profile(task_id, task_name, cmd, start_time, end_time,
|
88
|
+
def profile(task_id, task_name, cmd, start_time, end_time,
|
89
|
+
host=nil, ncore=nil, status=nil)
|
89
90
|
id = @lock.synchronize do
|
90
91
|
id = @id
|
91
92
|
@id += 1
|
@@ -96,7 +97,7 @@ module Pwrake
|
|
96
97
|
format_time(start_time),
|
97
98
|
format_time(end_time),
|
98
99
|
"%.3f" % (end_time-start_time),
|
99
|
-
host, status ]
|
100
|
+
host, ncore, status ]
|
100
101
|
end
|
101
102
|
case status
|
102
103
|
when ""
|
data/lib/pwrake/master/master.rb
CHANGED
@@ -144,7 +144,6 @@ module Pwrake
|
|
144
144
|
@task_queue = queue_class.new(@hostinfo_by_id)
|
145
145
|
|
146
146
|
@branch_setup_thread = Thread.new do
|
147
|
-
#@channels.each do |chan|
|
148
147
|
create_fiber(@hdl_set) do |hdl|
|
149
148
|
while s = hdl.get_line
|
150
149
|
case s
|
@@ -158,12 +157,6 @@ module Pwrake
|
|
158
157
|
end
|
159
158
|
end
|
160
159
|
@selector.run
|
161
|
-
@killed = 0
|
162
|
-
[:TERM,:INT].each do |sig|
|
163
|
-
Signal.trap(sig) do
|
164
|
-
signal_trap(sig)
|
165
|
-
end
|
166
|
-
end
|
167
160
|
end
|
168
161
|
|
169
162
|
end
|
@@ -190,8 +183,11 @@ module Pwrake
|
|
190
183
|
end
|
191
184
|
|
192
185
|
def invoke(t, args)
|
186
|
+
Log.debug "Master#invoke start: #{t.class}[#{t.name}]"
|
193
187
|
@failed = false
|
194
188
|
t.pw_search_tasks(args)
|
189
|
+
return if @running
|
190
|
+
@running = true
|
195
191
|
|
196
192
|
if @option['GRAPH_PARTITION']
|
197
193
|
setup_postprocess0
|
@@ -210,8 +206,17 @@ module Pwrake
|
|
210
206
|
|
211
207
|
setup_postprocess1
|
212
208
|
@branch_setup_thread.join
|
209
|
+
@killed = 0
|
210
|
+
[:TERM,:INT].each do |sig|
|
211
|
+
Signal.trap(sig) do
|
212
|
+
signal_trap(sig)
|
213
|
+
end
|
214
|
+
end
|
213
215
|
send_task_to_idle_core
|
214
|
-
|
216
|
+
setup_fiber(t)
|
217
|
+
end
|
218
|
+
|
219
|
+
def setup_fiber(t)
|
215
220
|
n_retry = @option["RETRY"]
|
216
221
|
create_fiber(@hdl_set) do |hdl|
|
217
222
|
while s = hdl.get_line
|
data/lib/pwrake/mpi/branch.rb
CHANGED
@@ -68,18 +68,18 @@ module Pwrake
|
|
68
68
|
|
69
69
|
def shift(host_info=nil)
|
70
70
|
return super() unless host_info
|
71
|
-
|
71
|
+
i_found = nil
|
72
72
|
(size-1).downto(0) do |i|
|
73
73
|
tw = at(i)
|
74
74
|
if tw.acceptable_for(host_info)
|
75
75
|
if tw.untried_host?(host_info)
|
76
76
|
return delete_at(i)
|
77
77
|
else
|
78
|
-
|
78
|
+
i_found ||= i
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
82
|
-
|
82
|
+
(i_found) ? delete_at(i_found) : nil
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
@@ -90,18 +90,18 @@ module Pwrake
|
|
90
90
|
|
91
91
|
def shift(host_info=nil)
|
92
92
|
return super() unless host_info
|
93
|
-
|
93
|
+
i_found = nil
|
94
94
|
size.times do |i|
|
95
95
|
tw = at(i)
|
96
96
|
if tw.acceptable_for(host_info)
|
97
97
|
if tw.untried_host?(host_info)
|
98
98
|
return delete_at(i)
|
99
99
|
else
|
100
|
-
|
100
|
+
i_found ||= i
|
101
101
|
end
|
102
102
|
end
|
103
103
|
end
|
104
|
-
|
104
|
+
(i_found) ? delete_at(i_found) : nil
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
@@ -172,18 +172,18 @@ module Pwrake
|
|
172
172
|
end
|
173
173
|
|
174
174
|
def pop_last_rank(r,host_info)
|
175
|
-
|
175
|
+
i_found = nil
|
176
176
|
(size-1).downto(0) do |i|
|
177
177
|
tw = at(i)
|
178
178
|
if tw.rank == r && tw.acceptable_for(host_info)
|
179
179
|
if tw.untried_host?(host_info)
|
180
180
|
return delete_at(i)
|
181
181
|
else
|
182
|
-
|
182
|
+
i_found ||= i
|
183
183
|
end
|
184
184
|
end
|
185
185
|
end
|
186
|
-
|
186
|
+
(i_found) ? delete_at(i_found) : nil
|
187
187
|
end
|
188
188
|
|
189
189
|
def hrf_delete(t)
|
@@ -88,23 +88,23 @@ module Pwrake
|
|
88
88
|
@hostinfo_by_id.each_value do |host_info|
|
89
89
|
#Log.debug "TaskQueue#deq_turn host_info=#{host_info.name}"
|
90
90
|
if (n = host_info.idle_cores) && n > 0
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
91
|
+
if turn_empty?(turn)
|
92
|
+
return queued
|
93
|
+
elsif tw = deq_impl(host_info,turn)
|
94
|
+
n_task_cores = tw.n_used_cores(host_info)
|
95
|
+
Log.debug "deq: #{tw.name} n_task_cores=#{n_task_cores}"
|
96
|
+
if host_info.idle_cores < n_task_cores
|
97
|
+
m = "task.n_used_cores=#{n_task_cores} must be "+
|
98
|
+
"<= host_info.idle_cores=#{host_info.idle_cores}"
|
99
|
+
Log.fatal m
|
100
|
+
raise RuntimeError,m
|
101
|
+
else
|
102
|
+
yield(tw,host_info,n_task_cores)
|
103
|
+
count += 1
|
104
|
+
queued += 1
|
105
|
+
end
|
105
106
|
end
|
106
107
|
end
|
107
|
-
end
|
108
108
|
end
|
109
109
|
break if count == 0
|
110
110
|
end
|
@@ -3,22 +3,28 @@ module Pwrake
|
|
3
3
|
module Parallelism
|
4
4
|
module_function
|
5
5
|
|
6
|
+
def push_time_event(a, row, start_time)
|
7
|
+
command = row['command']
|
8
|
+
if command == 'pwrake_profile_start'
|
9
|
+
start_time[0] = Time.parse(row['start_time'])
|
10
|
+
elsif command == 'pwrake_profile_end'
|
11
|
+
t = Time.parse(row['start_time']) - start_time[0]
|
12
|
+
a << [t,0]
|
13
|
+
elsif start_time[0]
|
14
|
+
n = begin Integer(row['ncore']) rescue 1 end
|
15
|
+
t = Time.parse(row['start_time']) - start_time[0]
|
16
|
+
a << [t,+n]
|
17
|
+
t = Time.parse(row['end_time']) - start_time[0]
|
18
|
+
a << [t,-n]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
6
22
|
def count_start_end_from_csv(file)
|
7
23
|
a = []
|
8
|
-
start_time =
|
24
|
+
start_time = []
|
9
25
|
|
10
26
|
CSV.foreach(file,:headers=>true) do |row|
|
11
|
-
|
12
|
-
start_time = Time.parse(row['start_time'])
|
13
|
-
elsif row['command'] == 'pwrake_profile_end'
|
14
|
-
t = Time.parse(row['start_time']) - start_time
|
15
|
-
a << [t,0]
|
16
|
-
elsif start_time
|
17
|
-
t = Time.parse(row['start_time']) - start_time
|
18
|
-
a << [t,+1]
|
19
|
-
t = Time.parse(row['end_time']) - start_time
|
20
|
-
a << [t,-1]
|
21
|
-
end
|
27
|
+
push_time_event(a, row, start_time)
|
22
28
|
end
|
23
29
|
|
24
30
|
a.sort{|x,y| x[0]<=>y[0]}
|
@@ -26,20 +32,10 @@ module Pwrake
|
|
26
32
|
|
27
33
|
def count_start_end_from_csv_table(csvtable)
|
28
34
|
a = []
|
29
|
-
start_time =
|
35
|
+
start_time = []
|
30
36
|
|
31
37
|
csvtable.each do |row|
|
32
|
-
|
33
|
-
start_time = Time.parse(row['start_time'])
|
34
|
-
elsif row['command'] == 'pwrake_profile_end'
|
35
|
-
t = Time.parse(row['start_time']) - start_time
|
36
|
-
a << [t,0]
|
37
|
-
elsif start_time
|
38
|
-
t = Time.parse(row['start_time']) - start_time
|
39
|
-
a << [t,+1]
|
40
|
-
t = Time.parse(row['end_time']) - start_time
|
41
|
-
a << [t,-1]
|
42
|
-
end
|
38
|
+
push_time_event(a, row, start_time)
|
43
39
|
end
|
44
40
|
|
45
41
|
a.sort{|x,y| x[0]<=>y[0]}
|
@@ -48,16 +44,15 @@ module Pwrake
|
|
48
44
|
def exec_density(a)
|
49
45
|
reso = 0.1
|
50
46
|
delta = 1/reso
|
51
|
-
t_end =
|
52
|
-
n = (t_end/reso).
|
53
|
-
i = 0
|
54
|
-
t_next = reso
|
47
|
+
t_end = a.last[0]
|
48
|
+
n = (t_end/reso).round + 1
|
55
49
|
d = (n+1).times.map{|i| [reso*i,0]}
|
50
|
+
i = 0
|
56
51
|
a.each do |x|
|
57
52
|
while d[i+1][0] <= x[0]
|
58
53
|
i += 1
|
59
54
|
end
|
60
|
-
if x[1]
|
55
|
+
if x[1] > 0
|
61
56
|
d[i][1] += delta
|
62
57
|
end
|
63
58
|
end
|
@@ -68,21 +63,21 @@ module Pwrake
|
|
68
63
|
a = count_start_end_from_csv(file)
|
69
64
|
return if a.size < 4
|
70
65
|
|
71
|
-
density = exec_density(a)
|
66
|
+
#density = exec_density(a)
|
72
67
|
|
73
68
|
base = file.sub(/\.csv$/,"")
|
74
69
|
fpara = base+"_para.dat"
|
75
70
|
|
76
71
|
n = a.size
|
77
|
-
i = 0
|
78
72
|
y = 0
|
79
73
|
y_max = 0
|
80
74
|
|
81
75
|
File.open(fpara,"w") do |f|
|
76
|
+
i = 0
|
77
|
+
t = 0
|
78
|
+
y_pre = 0
|
82
79
|
begin
|
83
|
-
|
84
|
-
y_pre = 0
|
85
|
-
n.times do |i|
|
80
|
+
while i < n
|
86
81
|
if a[i][0]-t > 0.001
|
87
82
|
f.printf "%.3f %d\n", t, y_pre
|
88
83
|
t = a[i][0]
|
@@ -91,6 +86,7 @@ module Pwrake
|
|
91
86
|
y += a[i][1]
|
92
87
|
y_pre = y
|
93
88
|
y_max = y if y > y_max
|
89
|
+
i += 1
|
94
90
|
end
|
95
91
|
rescue
|
96
92
|
p a[i]
|
@@ -136,7 +132,7 @@ plot '#{fpara}' w l axis x1y1 title 'parallelism'
|
|
136
132
|
begin
|
137
133
|
t = 0
|
138
134
|
y_pre = 0
|
139
|
-
|
135
|
+
while i < n
|
140
136
|
if a[i][0]-t > 0.001
|
141
137
|
para.push "%.3f %d" % [t, y_pre]
|
142
138
|
t = a[i][0]
|
@@ -145,6 +141,7 @@ plot '#{fpara}' w l axis x1y1 title 'parallelism'
|
|
145
141
|
y += a[i][1]
|
146
142
|
y_pre = y
|
147
143
|
y_max = y if y > y_max
|
144
|
+
i += 1
|
148
145
|
end
|
149
146
|
rescue
|
150
147
|
p a[i]
|
@@ -185,72 +182,65 @@ plot '-' w l axis x1y1 title 'parallelism', '-' w l axis x1y2 title 'exec/sec'
|
|
185
182
|
fimg
|
186
183
|
end
|
187
184
|
|
185
|
+
|
186
|
+
def push_time_by_key(h, row, key, start_time)
|
187
|
+
command = row['command']
|
188
|
+
if command == 'pwrake_profile_start'
|
189
|
+
start_time[0] = Time.parse(row['start_time'])
|
190
|
+
elsif command == 'pwrake_profile_end'
|
191
|
+
t = Time.parse(row['start_time']) - start_time[0]
|
192
|
+
h.each_value do |v|
|
193
|
+
v << [t,0]
|
194
|
+
end
|
195
|
+
elsif start_time[0]
|
196
|
+
a = (h[key] ||= [])
|
197
|
+
n = begin Integer(row['ncore']) rescue 1 end
|
198
|
+
t = Time.parse(row['start_time']) - start_time[0]
|
199
|
+
a << [t,+n]
|
200
|
+
t = Time.parse(row['end_time']) - start_time[0]
|
201
|
+
a << [t,-n]
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
188
205
|
def read_time_by_host_from_csv(csvtable)
|
189
206
|
a = {}
|
190
|
-
start_time =
|
207
|
+
start_time = []
|
191
208
|
|
192
209
|
csvtable.each do |row|
|
193
|
-
|
194
|
-
if row['command'] == 'pwrake_profile_start'
|
195
|
-
start_time = Time.parse(row['start_time'])
|
196
|
-
elsif row['command'] == 'pwrake_profile_end'
|
197
|
-
t = Time.parse(row['start_time']) - start_time
|
198
|
-
a.each do |h,v|
|
199
|
-
v << [t,0]
|
200
|
-
end
|
201
|
-
elsif start_time
|
202
|
-
a[host] ||= []
|
203
|
-
t = Time.parse(row['start_time']) - start_time
|
204
|
-
a[host] << [t,+1]
|
205
|
-
t = Time.parse(row['end_time']) - start_time
|
206
|
-
a[host] << [t,-1]
|
207
|
-
end
|
210
|
+
push_time_by_key(a, row, row['host'], start_time)
|
208
211
|
end
|
209
212
|
a
|
210
213
|
end
|
211
214
|
|
212
215
|
|
213
|
-
def get_command_key(s, pattern)
|
216
|
+
def get_command_key(s, pattern=[])
|
214
217
|
pattern.each do |cmd,regex|
|
215
218
|
if regex =~ s
|
216
219
|
return cmd
|
217
220
|
end
|
218
221
|
end
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
if
|
225
|
-
|
226
|
-
|
227
|
-
|
222
|
+
case s
|
223
|
+
when /^\s*\((.*)$/
|
224
|
+
get_command_key($1)
|
225
|
+
when /^\s*([\w.,~^\/=+-]+)(.*)$/
|
226
|
+
cmd, rest = $1, $2
|
227
|
+
if cmd == "cd" && /[^;]*;(.*)$/ =~ rest
|
228
|
+
return get_command_key($1)
|
229
|
+
else
|
230
|
+
cmd
|
228
231
|
end
|
232
|
+
else
|
233
|
+
s[0..15]
|
229
234
|
end
|
230
|
-
nil
|
231
235
|
end
|
232
236
|
|
233
237
|
def count_start_end_by_pattern(csvtable, pattern)
|
234
238
|
h = Hash.new
|
235
|
-
start_time =
|
239
|
+
start_time = []
|
236
240
|
|
237
241
|
csvtable.each do |row|
|
238
|
-
|
239
|
-
|
240
|
-
start_time = Time.parse(row['start_time'])
|
241
|
-
elsif command == 'pwrake_profile_end'
|
242
|
-
t = Time.parse(row['start_time']) - start_time
|
243
|
-
h.values.each do |a|
|
244
|
-
a << [t,0]
|
245
|
-
end
|
246
|
-
elsif start_time
|
247
|
-
cmd = get_command_key(command, pattern)
|
248
|
-
h[cmd] ||= []
|
249
|
-
t = Time.parse(row['start_time']) - start_time
|
250
|
-
h[cmd] << [t,+1]
|
251
|
-
t = Time.parse(row['end_time']) - start_time
|
252
|
-
h[cmd] << [t,-1]
|
253
|
-
end
|
242
|
+
cmd = get_command_key(row['command'], pattern)
|
243
|
+
push_time_by_key(h, row, cmd, start_time)
|
254
244
|
end
|
255
245
|
|
256
246
|
h.each do |k,a|
|
@@ -272,7 +262,7 @@ plot '-' w l axis x1y1 title 'parallelism', '-' w l axis x1y2 title 'exec/sec'
|
|
272
262
|
begin
|
273
263
|
t = 0
|
274
264
|
y_pre = 0
|
275
|
-
|
265
|
+
while i < n
|
276
266
|
if a[i][0]-t > 0.001
|
277
267
|
dat.push "%.3f %d" % [t, y_pre]
|
278
268
|
t = a[i][0]
|
@@ -281,6 +271,7 @@ plot '-' w l axis x1y1 title 'parallelism', '-' w l axis x1y2 title 'exec/sec'
|
|
281
271
|
y += a[i][1]
|
282
272
|
y_pre = y
|
283
273
|
y_max = y if y > y_max
|
274
|
+
i += 1
|
284
275
|
end
|
285
276
|
rescue
|
286
277
|
p a[i]
|
@@ -303,7 +294,7 @@ set xlabel 'time (sec)'
|
|
303
294
|
set ylabel 'parallelism'
|
304
295
|
"
|
305
296
|
f.print "plot "
|
306
|
-
f.puts para.map{|cmd,re| "'-' w l title
|
297
|
+
f.puts para.map{|cmd,re| "'-' w l title #{cmd.inspect}"}.join(",")
|
307
298
|
para.each do |cmd,dat|
|
308
299
|
dat.each do |x|
|
309
300
|
f.puts x
|
@@ -321,9 +312,8 @@ set ylabel 'parallelism'
|
|
321
312
|
resolution = Rational(1,10)
|
322
313
|
|
323
314
|
a = a.sort{|x,y| x[0]<=>y[0]}
|
324
|
-
t_end = (a.last)[0]
|
325
|
-
|
326
|
-
ngrid = (t_end/resolution).floor
|
315
|
+
#t_end = (a.last)[0]
|
316
|
+
#ngrid = (t_end/resolution).floor
|
327
317
|
grid = [[0,0]]
|
328
318
|
|
329
319
|
j = 0
|
data/lib/pwrake/report/report.rb
CHANGED
@@ -135,18 +135,42 @@ EOL
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def get_command(s)
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
138
|
+
case s
|
139
|
+
when /^\s*\((.*)$/
|
140
|
+
get_command($1)
|
141
|
+
when /^\s*([\w.,~^\/=+-]+)(.*)$/
|
142
|
+
cmd, rest = $1, $2
|
143
|
+
case cmd
|
144
|
+
when "cd"
|
145
|
+
if /[^;]*;(.*)$/ =~ rest
|
146
|
+
return get_command($1)
|
147
|
+
end
|
148
|
+
when /^ruby[\d.]*$/
|
149
|
+
case rest
|
150
|
+
when /([\w.,~^\/=+-]+\.rb)\b/
|
151
|
+
return "#{cmd} #{$1}"
|
152
|
+
when /\s+-e\s+("[^"]*"|'[^']*'|\S+)/
|
153
|
+
return "#{cmd} -e #{$1}"
|
154
|
+
end
|
155
|
+
when /^python[\d.]*$/
|
156
|
+
case rest
|
157
|
+
when /([\w.,~^\/=+-]+\.py)\b/
|
158
|
+
return "#{cmd} #{$1}"
|
159
|
+
when /\s+-c\s+("[^"]*"|'[^']*'|\S+)/
|
160
|
+
return "python -c #{$1}"
|
161
|
+
end
|
162
|
+
when /^perl[\d.]*$/
|
163
|
+
case rest
|
164
|
+
when /([\w.,~^\/=+-]+\.pl)\b/
|
165
|
+
return "#{cmd} #{$1}"
|
166
|
+
when /\s+-e\s+("[^"]*"|'[^']*'|\S+)/
|
167
|
+
return "#{cmd} -e #{$1}"
|
168
|
+
end
|
147
169
|
end
|
170
|
+
cmd
|
171
|
+
else
|
172
|
+
s[0..15]
|
148
173
|
end
|
149
|
-
nil
|
150
174
|
end
|
151
175
|
|
152
176
|
def make_cmd_stat
|
@@ -299,9 +323,9 @@ set logscale x
|
|
299
323
|
set title 'histogram of elapsed time'"
|
300
324
|
a = []
|
301
325
|
|
302
|
-
command_list.each_with_index do |
|
326
|
+
command_list.each_with_index do |cmd,i|
|
303
327
|
a << "'-' w histeps ls #{i+1} title ''"
|
304
|
-
a << "'-' w lines ls #{i+1} title
|
328
|
+
a << "'-' w lines ls #{i+1} title #{cmd.inspect}"
|
305
329
|
end
|
306
330
|
f.puts "plot "+ a.join(',')
|
307
331
|
|
@@ -5,22 +5,25 @@ module Pwrake
|
|
5
5
|
|
6
6
|
module TaskAlgorithm
|
7
7
|
|
8
|
-
attr_reader :wrapper
|
9
8
|
attr_reader :subsequents
|
10
9
|
attr_reader :arguments
|
11
10
|
attr_reader :property
|
12
11
|
attr_reader :unfinished_prereq
|
13
12
|
|
13
|
+
def wrapper
|
14
|
+
if @wrapper.nil?
|
15
|
+
raise "TaskWrapper is not defined for #{self.class}[#{name}]"
|
16
|
+
end
|
17
|
+
@wrapper
|
18
|
+
end
|
19
|
+
|
14
20
|
def pw_search_tasks(args)
|
15
|
-
Log.debug "#{self.class}#pw_search_tasks start, args=#{args.inspect}"
|
21
|
+
Log.debug "#{self.class}#pw_search_tasks start, task=#{name} args=#{args.inspect}"
|
16
22
|
tm = Time.now
|
17
23
|
task_args = TaskArguments.new(arg_names, args)
|
18
|
-
#
|
19
|
-
|
20
|
-
#
|
21
|
-
search_with_call_chain(nil, task_args, InvocationChain::EMPTY)
|
22
|
-
#end
|
23
|
-
#timer.finish
|
24
|
+
# not synchronize owing to fiber
|
25
|
+
search_with_call_chain(nil, task_args, InvocationChain::EMPTY)
|
26
|
+
#
|
24
27
|
Log.debug "#{self.class}#pw_search_tasks end #{Time.now-tm}"
|
25
28
|
end
|
26
29
|
|
@@ -30,7 +33,7 @@ module Pwrake
|
|
30
33
|
new_chain = InvocationChain.append(self, invocation_chain)
|
31
34
|
@lock.synchronize do
|
32
35
|
if application.options.trace
|
33
|
-
#Log.
|
36
|
+
#Log.debug "** Search #{name} #{format_search_flags}"
|
34
37
|
application.trace "** Search #{name} #{format_search_flags}"
|
35
38
|
end
|
36
39
|
|
@@ -48,7 +51,7 @@ module Pwrake
|
|
48
51
|
search_prerequisites(task_args, new_chain)
|
49
52
|
end
|
50
53
|
#check_and_enq
|
51
|
-
if @unfinished_prereq.empty?
|
54
|
+
if !@already_finished && @unfinished_prereq.empty?
|
52
55
|
application.task_queue.enq(@wrapper)
|
53
56
|
end
|
54
57
|
end
|
@@ -82,23 +85,18 @@ module Pwrake
|
|
82
85
|
private :format_search_flags
|
83
86
|
|
84
87
|
def pw_enq_subsequents
|
85
|
-
#
|
86
|
-
#
|
87
|
-
|
88
|
-
|
89
|
-
#u = t.unfinished_prereq.keys
|
90
|
-
#Log.debug "enq_subseq: self=#{self.name} subseq=#{t.name} @unfin_preq=#{u.inspect}"
|
91
|
-
if t && t.check_prereq_finished(self.name)
|
92
|
-
application.task_queue.enq(t.wrapper)
|
93
|
-
end
|
88
|
+
# not synchronize owing to fiber
|
89
|
+
@subsequents.each do |t| # <<--- competition !!!
|
90
|
+
if t && t.check_prereq_finished(self.name)
|
91
|
+
application.task_queue.enq(t.wrapper)
|
94
92
|
end
|
95
|
-
|
93
|
+
end
|
96
94
|
@already_finished = true # <<--- competition !!!
|
97
95
|
end
|
98
96
|
|
99
97
|
def check_prereq_finished(preq_name=nil)
|
100
98
|
@unfinished_prereq.delete(preq_name)
|
101
|
-
@unfinished_prereq.empty?
|
99
|
+
!@already_finished && @unfinished_prereq.empty?
|
102
100
|
end
|
103
101
|
|
104
102
|
def pw_set_property(property)
|
@@ -106,5 +104,18 @@ module Pwrake
|
|
106
104
|
self
|
107
105
|
end
|
108
106
|
|
107
|
+
end # TaskAlgorithm
|
108
|
+
|
109
|
+
|
110
|
+
module TaskInvoke
|
111
|
+
|
112
|
+
def invoke(*args)
|
113
|
+
Rake.application.invoke(self,*args)
|
114
|
+
end
|
115
|
+
|
116
|
+
def reenable
|
117
|
+
@already_invoked = false
|
118
|
+
@already_searched = false
|
119
|
+
end
|
109
120
|
end
|
110
121
|
end
|
@@ -53,8 +53,9 @@ module Pwrake
|
|
53
53
|
fn = File.join(dir,option['TASK_CSV_FILE'])
|
54
54
|
@@task_logger = CSV.open(fn,'w')
|
55
55
|
@@task_logger.puts %w[
|
56
|
-
task_id task_name start_time end_time elap_time preq
|
57
|
-
exec_host shell_id has_action executed
|
56
|
+
task_id task_name start_time end_time elap_time preq
|
57
|
+
preq_host preq_loc exec_host shell_id has_action executed ncore
|
58
|
+
file_size file_mtime file_host write_loc
|
58
59
|
]
|
59
60
|
end
|
60
61
|
end
|
@@ -64,9 +65,6 @@ module Pwrake
|
|
64
65
|
end
|
65
66
|
|
66
67
|
def preprocess
|
67
|
-
if @shell = Pwrake::Shell.current
|
68
|
-
@shell.current_task = self
|
69
|
-
end
|
70
68
|
@time_start = Time.now
|
71
69
|
end
|
72
70
|
|
@@ -90,7 +88,6 @@ module Pwrake
|
|
90
88
|
end
|
91
89
|
#Log.debug "postprocess time=#{Time.now-tm_taskend}"
|
92
90
|
log_task
|
93
|
-
@shell.current_task = nil if @shell
|
94
91
|
end
|
95
92
|
|
96
93
|
def retry_or_subsequent
|
@@ -142,18 +139,21 @@ module Pwrake
|
|
142
139
|
write_loc = file_locality(@location)
|
143
140
|
#
|
144
141
|
if @file_stat
|
145
|
-
fstat = [@file_stat.size, @file_stat.mtime,
|
142
|
+
fstat = [ @file_stat.size, @file_stat.mtime,
|
143
|
+
self.location.join('|'), write_loc ]
|
146
144
|
else
|
147
145
|
fstat = [nil]*4
|
148
146
|
end
|
149
147
|
#
|
150
|
-
# task_id task_name start_time end_time elap_time preq preq_host
|
151
|
-
# exec_host shell_id has_action executed
|
148
|
+
# task_id task_name start_time end_time elap_time preq preq_host
|
149
|
+
# preq_loc exec_host shell_id has_action executed ncore
|
150
|
+
# file_size file_mtime file_host write_loc
|
152
151
|
#
|
153
152
|
row = [ @task_id, name, @time_start, @time_end, elap,
|
154
153
|
prerequisites, sug_host, preq_loc, @exec_host, @shell_id,
|
155
154
|
(actions.empty?) ? 0 : 1,
|
156
155
|
(@executed) ? 1 : 0,
|
156
|
+
@n_used_cores,
|
157
157
|
] + fstat
|
158
158
|
row.map!{|x|
|
159
159
|
if x.kind_of?(Time)
|
data/lib/pwrake/version.rb
CHANGED
@@ -2,6 +2,43 @@ module Pwrake
|
|
2
2
|
|
3
3
|
class Executor
|
4
4
|
|
5
|
+
ENV = {
|
6
|
+
"OMPI_APP_CTX_NUM_PROCS" => nil,
|
7
|
+
"OMPI_COMM_WORLD_LOCAL_RANK" => nil,
|
8
|
+
"OMPI_COMM_WORLD_LOCAL_SIZE" => nil,
|
9
|
+
"OMPI_COMM_WORLD_NODE_RANK" => nil,
|
10
|
+
"OMPI_COMM_WORLD_RANK" => nil,
|
11
|
+
"OMPI_COMM_WORLD_SIZE" => nil,
|
12
|
+
"OMPI_FILE_LOCATION" => nil,
|
13
|
+
"OMPI_FIRST_RANKS" => nil,
|
14
|
+
"OMPI_MCA_db" => nil,
|
15
|
+
"OMPI_MCA_ess" => nil,
|
16
|
+
"OMPI_MCA_ess_base_jobid" => nil,
|
17
|
+
"OMPI_MCA_ess_base_vpid" => nil,
|
18
|
+
"OMPI_MCA_grpcomm" => nil,
|
19
|
+
"OMPI_MCA_initial_wdir" => nil,
|
20
|
+
"OMPI_MCA_mpi_yield_when_idle" => nil,
|
21
|
+
"OMPI_MCA_orte_app_num" => nil,
|
22
|
+
"OMPI_MCA_orte_bound_at_launch" => nil,
|
23
|
+
"OMPI_MCA_orte_ess_jobid" => nil,
|
24
|
+
"OMPI_MCA_orte_ess_node_rank" => nil,
|
25
|
+
"OMPI_MCA_orte_ess_num_procs" => nil,
|
26
|
+
"OMPI_MCA_orte_ess_vpid" => nil,
|
27
|
+
"OMPI_MCA_orte_hnp_uri" => nil,
|
28
|
+
"OMPI_MCA_orte_local_daemon_uri" => nil,
|
29
|
+
"OMPI_MCA_orte_num_nodes" => nil,
|
30
|
+
"OMPI_MCA_orte_num_restarts" => nil,
|
31
|
+
"OMPI_MCA_orte_tmpdir_base" => nil,
|
32
|
+
"OMPI_MCA_plm" => nil,
|
33
|
+
"OMPI_MCA_pubsub" => nil,
|
34
|
+
"OMPI_MCA_shmem_RUNTIME_QUERY_hint" => nil,
|
35
|
+
"OMPI_NUM_APP_CTX" => nil,
|
36
|
+
"OMPI_UNIVERSE_SIZE" => nil,
|
37
|
+
"PMI_RANK" => nil,
|
38
|
+
"PMI_FD" => nil,
|
39
|
+
"PMI_SIZE" => nil,
|
40
|
+
}
|
41
|
+
|
5
42
|
def initialize(selector,dir_class,id)
|
6
43
|
@selector = selector
|
7
44
|
@id = id
|
@@ -74,7 +111,7 @@ module Pwrake
|
|
74
111
|
@sh_out, @spawn_out = IO.pipe
|
75
112
|
@sh_err, @spawn_err = IO.pipe
|
76
113
|
|
77
|
-
@pid = Kernel.spawn(command,
|
114
|
+
@pid = Kernel.spawn(ENV, command,
|
78
115
|
:in=>@spawn_in,
|
79
116
|
:out=>@spawn_out,
|
80
117
|
:err=>@spawn_err,
|
@@ -86,15 +86,18 @@ module Pwrake
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def run
|
89
|
+
run_setup
|
90
|
+
run_command
|
91
|
+
ensure
|
92
|
+
close_all
|
93
|
+
end
|
94
|
+
|
95
|
+
def run_setup
|
89
96
|
setup_option
|
90
97
|
Fiber.new{setup_loop}.resume
|
91
98
|
@selector.run
|
92
|
-
Fiber.new{command_callback}.resume
|
93
|
-
@selector.run
|
94
99
|
rescue => exc
|
95
100
|
@log.error(([exc.to_s]+exc.backtrace).join("\n"))
|
96
|
-
ensure
|
97
|
-
close_all
|
98
101
|
end
|
99
102
|
|
100
103
|
def setup_option
|
@@ -123,6 +126,14 @@ module Pwrake
|
|
123
126
|
end
|
124
127
|
end
|
125
128
|
|
129
|
+
def run_command
|
130
|
+
Fiber.new{command_callback}.resume
|
131
|
+
@selector.run
|
132
|
+
rescue => exc
|
133
|
+
@log.error(([exc.to_s]+exc.backtrace).join("\n"))
|
134
|
+
kill_all("TERM")
|
135
|
+
end
|
136
|
+
|
126
137
|
def command_callback
|
127
138
|
while line = get_line(@rd)
|
128
139
|
case line
|
@@ -152,8 +163,7 @@ module Pwrake
|
|
152
163
|
when /^kill:(.*)$/o
|
153
164
|
sig = $1
|
154
165
|
sig = sig.to_i if /^\d+$/o =~ sig
|
155
|
-
|
156
|
-
@ex_list.each{|id,ex| ex.kill(sig)}
|
166
|
+
kill_all(sig)
|
157
167
|
return false
|
158
168
|
#
|
159
169
|
when /^p$/o
|
@@ -167,6 +177,11 @@ module Pwrake
|
|
167
177
|
end
|
168
178
|
end
|
169
179
|
|
180
|
+
def kill_all(sig)
|
181
|
+
@log.warn "killing worker, signal=#{sig}"
|
182
|
+
@ex_list.each{|id,ex| ex.kill(sig)}
|
183
|
+
end
|
184
|
+
|
170
185
|
def close_all
|
171
186
|
@log.info "close_all"
|
172
187
|
@heartbeat_thread.kill if @heartbeat_thread
|
data/lib/pwrake/worker/writer.rb
CHANGED
@@ -8,9 +8,8 @@ module Pwrake
|
|
8
8
|
def initialize
|
9
9
|
@out = $stderr
|
10
10
|
@mutex = Mutex.new
|
11
|
-
@mutex_hb = Mutex.new
|
12
11
|
@cond_hb = true
|
13
|
-
@heartbeat =
|
12
|
+
@heartbeat = 120
|
14
13
|
@thread = Thread.new{ heartbeat_loop }
|
15
14
|
end
|
16
15
|
|
@@ -22,14 +21,13 @@ module Pwrake
|
|
22
21
|
end
|
23
22
|
|
24
23
|
def heartbeat_loop
|
24
|
+
sleep
|
25
25
|
loop do
|
26
|
-
|
27
|
-
@
|
28
|
-
|
29
|
-
_puts "heartbeat"
|
30
|
-
end
|
31
|
-
@cond_hb = true
|
26
|
+
sleep(@heartbeat)
|
27
|
+
if @cond_hb
|
28
|
+
_puts "heartbeat"
|
32
29
|
end
|
30
|
+
@cond_hb = true
|
33
31
|
end
|
34
32
|
end
|
35
33
|
|
@@ -38,25 +36,11 @@ module Pwrake
|
|
38
36
|
end
|
39
37
|
|
40
38
|
def puts(s)
|
41
|
-
@
|
42
|
-
|
43
|
-
@thread.run
|
44
|
-
end
|
39
|
+
@cond_hb = false
|
40
|
+
@thread.run
|
45
41
|
_puts(s)
|
46
42
|
end
|
47
43
|
|
48
|
-
def _puts(s)
|
49
|
-
begin
|
50
|
-
@mutex.synchronize do
|
51
|
-
@out.print s+"\n"
|
52
|
-
end
|
53
|
-
@out.flush
|
54
|
-
rescue Errno::EPIPE => e
|
55
|
-
@log.info "<#{e.inspect}" if @log
|
56
|
-
end
|
57
|
-
@log.info "<#{s}" if @log
|
58
|
-
end
|
59
|
-
|
60
44
|
def flush
|
61
45
|
begin
|
62
46
|
@out.flush
|
@@ -68,5 +52,17 @@ module Pwrake
|
|
68
52
|
puts(s) if $DEBUG
|
69
53
|
end
|
70
54
|
|
55
|
+
private
|
56
|
+
def _puts(s)
|
57
|
+
begin
|
58
|
+
@mutex.synchronize do
|
59
|
+
@out.print s+"\n"
|
60
|
+
end
|
61
|
+
@out.flush
|
62
|
+
rescue Errno::EPIPE => e
|
63
|
+
@log.info "<#{e.inspect}" if @log
|
64
|
+
end
|
65
|
+
@log.info "<#{s}" if @log
|
66
|
+
end
|
71
67
|
end
|
72
68
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pwrake
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masahiro TANAKA
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parallel
|
@@ -136,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
136
|
version: '0'
|
137
137
|
requirements: []
|
138
138
|
rubyforge_project:
|
139
|
-
rubygems_version: 2.6.
|
139
|
+
rubygems_version: 2.6.11
|
140
140
|
signing_key:
|
141
141
|
specification_version: 4
|
142
142
|
summary: Parallel Workflow engine based on Rake
|