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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f781cdfe39747649da0fafb2ebb37e579d294483
4
- data.tar.gz: 5985be277367367065e9fef64188fc43ec8a2de4
3
+ metadata.gz: 165b50b8450d65b495aefffe22cc3a8e02ae3828
4
+ data.tar.gz: 210a2fcb2b42cb1b70696e84595e20dd71332c83
5
5
  SHA512:
6
- metadata.gz: 847964dd1146902e2f6f5988a26188184845e1b7879ed43a311560266e90d33d3c5febe7bb6727cc2003075b540046028a6cbaea6c28451888866d1e43aa1cfe
7
- data.tar.gz: 76af1e8e961e9ff22e1c6ca0626a416eb73f2f43a9ce83c0c4b72a311841fd319b6a99c1fbf9594cbf5a4efafe8dc00833dae772550b705837f58e40f48ad69a
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
@@ -14,7 +14,7 @@ class CommunicatorSet
14
14
  @error_host = []
15
15
  @initial_communicators = []
16
16
  if hb = @option[:heartbeat]
17
- @heartbeat_timeout = hb + 15
17
+ @heartbeat_timeout = hb + 30
18
18
  end
19
19
  init_hosts
20
20
  end
@@ -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
- start_time, end_time, host, @status)
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, host=nil, status=nil)
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 ""
@@ -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
@@ -52,6 +52,10 @@ module Pwrake
52
52
  @master.invoke(t,args)
53
53
  end
54
54
 
55
+ def invoke(t,*args)
56
+ @master.invoke(t,args)
57
+ end
58
+
55
59
  def standard_rake_options
56
60
  opts = super
57
61
  opts.each_with_index do |a,i|
@@ -19,6 +19,7 @@ end
19
19
 
20
20
  class Rake::Task
21
21
  include Pwrake::TaskAlgorithm
22
+ prepend Pwrake::TaskInvoke
22
23
  end
23
24
 
24
25
  module Pwrake
@@ -68,18 +68,18 @@ module Pwrake
68
68
 
69
69
  def shift(host_info=nil)
70
70
  return super() unless host_info
71
- tw_found = nil
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
- tw_found ||= tw
78
+ i_found ||= i
79
79
  end
80
80
  end
81
81
  end
82
- tw_found
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
- tw_found = nil
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
- tw_found ||= tw
100
+ i_found ||= i
101
101
  end
102
102
  end
103
103
  end
104
- tw_found
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
- tw_found = nil
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
- tw_found ||= tw
182
+ i_found ||= i
183
183
  end
184
184
  end
185
185
  end
186
- tw_found
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
- 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
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 = nil
24
+ start_time = []
9
25
 
10
26
  CSV.foreach(file,:headers=>true) do |row|
11
- if row['command'] == 'pwrake_profile_start'
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 = nil
35
+ start_time = []
30
36
 
31
37
  csvtable.each do |row|
32
- if row['command'] == 'pwrake_profile_start'
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 = (a.last)[0]
52
- n = (t_end/reso).to_i + 1
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] == 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
- t = 0
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
- n.times do |i|
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 = nil
207
+ start_time = []
191
208
 
192
209
  csvtable.each do |row|
193
- host = row['host']
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
- if /\(([^()]+)\)/ =~ s
220
- s = $1
221
- end
222
- a = s.split(/;/)
223
- a.each do |x|
224
- if /^\s*(\S+)/ =~ x
225
- k = $1
226
- next if k=='cd'
227
- return k
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 = nil
239
+ start_time = []
236
240
 
237
241
  csvtable.each do |row|
238
- command = row['command']
239
- if command == 'pwrake_profile_start'
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
- n.times do |i|
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 '#{cmd}'"}.join(",")
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
@@ -135,18 +135,42 @@ EOL
135
135
  end
136
136
 
137
137
  def get_command(s)
138
- if /\(([^()]+)\)/ =~ s
139
- s = $1
140
- end
141
- a = s.split(/;/)
142
- a.each do |x|
143
- if /^\s*(\S+)/ =~ x
144
- k = $1
145
- next if k=='cd'
146
- return k
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 |n,i|
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 '#{n}'"
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
- #timer = Timer.new("search_task")
19
- #h = application.pwrake_options['HALT_QUEUE_WHILE_SEARCH']
20
- #application.task_queue.synchronize(h) do
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.info "** Search #{name} #{format_search_flags}"
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
- #t = Time.now
86
- #h = application.pwrake_options['HALT_QUEUE_WHILE_SEARCH']
87
- #application.task_queue.synchronize(h) do
88
- @subsequents.each do |t| # <<--- competition !!!
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
- #end
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 preq_host preq_loc
57
- exec_host shell_id has_action executed file_size file_mtime file_host write_loc
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, self.location.join('|'), write_loc]
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 preq_loc
151
- # exec_host shell_id has_action executed file_size file_mtime file_host write_loc
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)
@@ -1,3 +1,3 @@
1
1
  module Pwrake
2
- VERSION = "2.2.0"
2
+ VERSION = "2.2.1"
3
3
  end
@@ -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
- @log.warn "killing worker, signal=#{sig}"
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
@@ -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 = nil
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
- @heartbeat ? sleep(@heartbeat) : sleep
27
- @mutex_hb.synchronize do
28
- if @cond_hb
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
- @mutex_hb.synchronize do
42
- @cond_hb = false
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.0
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-02-22 00:00:00.000000000 Z
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.8
139
+ rubygems_version: 2.6.11
140
140
  signing_key:
141
141
  specification_version: 4
142
142
  summary: Parallel Workflow engine based on Rake