pwrake 2.2.9 → 2.3.0
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/README.md +5 -2
- data/lib/pwrake/branch/communicator_set.rb +1 -1
- data/lib/pwrake/master/master.rb +16 -13
- data/lib/pwrake/option/host_map.rb +11 -25
- data/lib/pwrake/option/option.rb +6 -3
- data/lib/pwrake/option/option_default_filesystem.rb +1 -1
- data/lib/pwrake/option/option_gfarm2fs.rb +1 -1
- data/lib/pwrake/queue/locality_aware_queue.rb +77 -84
- data/lib/pwrake/queue/non_locality_queue.rb +72 -0
- data/lib/pwrake/queue/queue_array.rb +75 -312
- data/lib/pwrake/queue/task_queue.rb +54 -91
- data/lib/pwrake/report/parallelism.rb +4 -6
- data/lib/pwrake/task/task_algorithm.rb +1 -0
- data/lib/pwrake/task/task_property.rb +49 -21
- data/lib/pwrake/task/task_wrapper.rb +17 -4
- data/lib/pwrake/version.rb +1 -1
- data/lib/pwrake/worker/executor.rb +1 -0
- data/lib/pwrake/worker/gfarm_directory.rb +38 -6
- data/lib/pwrake/worker/shared_directory.rb +3 -0
- metadata +3 -2
@@ -0,0 +1,72 @@
|
|
1
|
+
require "pwrake/queue/task_queue"
|
2
|
+
require "pwrake/queue/queue_array"
|
3
|
+
require "pwrake/queue/no_action_queue"
|
4
|
+
|
5
|
+
module Pwrake
|
6
|
+
|
7
|
+
class NonLocalityQueue
|
8
|
+
|
9
|
+
def initialize(hostinfo_by_id, array_class, median_core, group_map=nil)
|
10
|
+
@hostinfo_by_id = hostinfo_by_id
|
11
|
+
@array_class = array_class
|
12
|
+
@median_core = median_core
|
13
|
+
@disable_rank = Rake.application.pwrake_options['DISABLE_RANK_PRIORITY']
|
14
|
+
Log.debug "#{self.class}: @disable_rank=#{@disable_rank.inspect}"
|
15
|
+
@q_input = @array_class.new(@median_core)
|
16
|
+
@q_no_input = FifoQueueArray.new(@median_core)
|
17
|
+
@turns = [0]
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :turns
|
21
|
+
|
22
|
+
def enq_impl(tw)
|
23
|
+
if tw.has_input_file?
|
24
|
+
@q_input.push(tw)
|
25
|
+
else
|
26
|
+
@q_no_input.push(tw)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def turn_empty?(turn)
|
31
|
+
empty?
|
32
|
+
end
|
33
|
+
|
34
|
+
def deq_start
|
35
|
+
@rank = @disable_rank ? 0 : @q_input.find_rank(@median_core)
|
36
|
+
end
|
37
|
+
|
38
|
+
def deq_impl(host_info, turn)
|
39
|
+
case turn
|
40
|
+
when 0
|
41
|
+
@q_input.shift(host_info,@rank) ||
|
42
|
+
@q_no_input.shift(host_info,@rank)
|
43
|
+
else
|
44
|
+
raise "invalid turn: #{turn}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def size
|
49
|
+
@q_input.size +
|
50
|
+
@q_no_input.size
|
51
|
+
end
|
52
|
+
|
53
|
+
def clear
|
54
|
+
@q_input.clear
|
55
|
+
@q_no_input.clear
|
56
|
+
end
|
57
|
+
|
58
|
+
def empty?
|
59
|
+
@q_input.empty? &&
|
60
|
+
@q_no_input.empty?
|
61
|
+
end
|
62
|
+
|
63
|
+
def inspect_q
|
64
|
+
TaskQueue._qstr("input", @q_input) +
|
65
|
+
TaskQueue._qstr("no_input",@q_no_input)
|
66
|
+
end
|
67
|
+
|
68
|
+
def drop_host(host_info)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -3,227 +3,137 @@ require "pwrake/task/task_rank"
|
|
3
3
|
|
4
4
|
module Pwrake
|
5
5
|
|
6
|
-
class
|
7
|
-
def initialize(n)
|
8
|
-
super()
|
9
|
-
end
|
10
|
-
|
11
|
-
def shift
|
12
|
-
pop
|
13
|
-
end
|
6
|
+
class QueueArray < Array
|
14
7
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
super(t)
|
19
|
-
elsif first.priority > priority
|
20
|
-
unshift(t)
|
21
|
-
else
|
22
|
-
lower = 0
|
23
|
-
upper = size-1
|
24
|
-
while lower+1 < upper
|
25
|
-
mid = ((lower + upper) / 2).to_i
|
26
|
-
if self[mid].priority <= priority
|
27
|
-
lower = mid
|
28
|
-
else
|
29
|
-
upper = mid
|
30
|
-
end
|
31
|
-
end
|
32
|
-
insert(upper,t)
|
33
|
-
end
|
8
|
+
def initialize(nproc)
|
9
|
+
@nproc = nproc
|
10
|
+
super()
|
34
11
|
end
|
35
12
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
else
|
44
|
-
lower = 0
|
45
|
-
upper = size-1
|
46
|
-
while lower+1 < upper
|
47
|
-
mid = ((lower + upper) / 2).to_i
|
48
|
-
if self[mid].priority < priority
|
49
|
-
lower = mid
|
13
|
+
def shift(host_info, req_rank=0)
|
14
|
+
i_tried = nil
|
15
|
+
size.times do |i|
|
16
|
+
tw = q_at(i)
|
17
|
+
if tw.rank >= req_rank && tw.acceptable_for(host_info)
|
18
|
+
if tw.tried_host?(host_info)
|
19
|
+
i_tried ||= i
|
50
20
|
else
|
51
|
-
|
21
|
+
Log.debug "#{self.class}: task=#{tw.name} i=#{i}/#{size} rank=#{tw.rank}"
|
22
|
+
return q_delete_at(i)
|
52
23
|
end
|
53
24
|
end
|
54
|
-
mid = upper
|
55
|
-
if self[mid].priority == priority
|
56
|
-
Log.debug "TQA#index=#{mid}, priority=#{priority}"
|
57
|
-
mid
|
58
|
-
end
|
59
25
|
end
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
class LifoQueueArray < Array
|
65
|
-
def initialize(n_cores=nil)
|
66
|
-
super()
|
67
|
-
end
|
68
|
-
|
69
|
-
def shift(host_info=nil)
|
70
|
-
return super() unless host_info
|
71
|
-
i_tried = []
|
72
|
-
(size-1).downto(0) do |i|
|
73
|
-
tw = at(i)
|
74
|
-
if tw.tried_host?(host_info)
|
75
|
-
i_tried << i
|
76
|
-
elsif tw.acceptable_for(host_info)
|
77
|
-
return delete_at(i)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
i_tried.each do |i|
|
81
|
-
tw = at(i)
|
82
|
-
if tw.acceptable_for(host_info)
|
83
|
-
return delete_at(i)
|
84
|
-
end
|
26
|
+
if i_tried
|
27
|
+
tw = q_at(i_tried)
|
28
|
+
Log.debug "#{self.class}(retry): task=#{tw.name} i=#{i_tried}/#{size} rank=#{tw.rank}"
|
29
|
+
return q_delete_at(i_tried)
|
85
30
|
end
|
86
31
|
nil
|
87
32
|
end
|
88
|
-
end
|
89
33
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end
|
94
|
-
|
95
|
-
def shift(host_info=nil)
|
96
|
-
return super() unless host_info
|
97
|
-
i_tried = []
|
98
|
-
size.times do |i|
|
99
|
-
tw = at(i)
|
100
|
-
if tw.tried_host?(host_info)
|
101
|
-
i_tried << i
|
102
|
-
elsif tw.acceptable_for(host_info)
|
103
|
-
return delete_at(i)
|
104
|
-
end
|
34
|
+
def find_rank(ncore)
|
35
|
+
if empty?
|
36
|
+
return 0
|
105
37
|
end
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
38
|
+
count = []
|
39
|
+
size.times do |i|
|
40
|
+
tw = q_at(i)
|
41
|
+
r = tw.rank
|
42
|
+
c = (count[r]||0) + tw.use_cores(ncore)
|
43
|
+
if c >= @nproc
|
44
|
+
return r
|
110
45
|
end
|
46
|
+
count[r] = c
|
111
47
|
end
|
112
|
-
|
48
|
+
count.size - 1
|
113
49
|
end
|
114
|
-
end
|
115
50
|
|
116
|
-
|
51
|
+
end
|
117
52
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
@mutex = Mutex.new
|
53
|
+
class LifoQueueArray < QueueArray
|
54
|
+
def q_at(i)
|
55
|
+
at(size-1-i)
|
122
56
|
end
|
123
|
-
|
124
|
-
|
125
|
-
@mutex.synchronize do
|
126
|
-
@nproc += n
|
127
|
-
end
|
57
|
+
def q_delete_at(i)
|
58
|
+
delete_at(size-1-i)
|
128
59
|
end
|
60
|
+
end
|
129
61
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
end
|
62
|
+
class FifoQueueArray < QueueArray
|
63
|
+
def q_at(i)
|
64
|
+
at(i)
|
134
65
|
end
|
135
|
-
|
136
|
-
|
137
|
-
@mutex.synchronize do
|
138
|
-
(@ntask.size-1).downto(0) do |r|
|
139
|
-
c = @ntask[r]
|
140
|
-
if c && c>0
|
141
|
-
t = yield(c, @nproc, r)
|
142
|
-
#t = (c<=@n) ? pop_last_rank(r) : pop
|
143
|
-
if t
|
144
|
-
@ntask[t.rank] -= 1
|
145
|
-
Log.debug "RankCount rank=#{r} nproc=#{@nproc} count=#{c} t.rank=#{t.rank} t.name=#{t.name}"
|
146
|
-
end
|
147
|
-
return t
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
nil
|
66
|
+
def q_delete_at(i)
|
67
|
+
delete_at(i)
|
152
68
|
end
|
153
69
|
end
|
154
70
|
|
71
|
+
|
155
72
|
# HRF mixin module
|
156
73
|
module HrfQueue
|
157
74
|
|
158
|
-
def hrf_init(
|
159
|
-
@nproc =
|
75
|
+
def hrf_init(nproc)
|
76
|
+
@nproc = nproc
|
160
77
|
@count = []
|
161
78
|
end
|
162
79
|
|
163
80
|
def hrf_push(t)
|
164
81
|
r = t.rank
|
165
|
-
|
166
|
-
@count[r] = (
|
82
|
+
n = t.use_cores(@nproc)
|
83
|
+
@count[r] = (@count[r] || 0) + n
|
167
84
|
end
|
168
85
|
|
169
|
-
def hrf_get(host_info)
|
170
|
-
(@count.size-1).downto(
|
86
|
+
def hrf_get(host_info, rank)
|
87
|
+
(@count.size-1).downto(rank) do |r|
|
171
88
|
c = @count[r]
|
172
89
|
if c && c>0
|
173
|
-
t = (c <= @nproc) ?
|
90
|
+
t = (c <= @nproc) ?
|
91
|
+
pop_last_rank(r, host_info) :
|
92
|
+
pop_super(host_info, rank)
|
174
93
|
hrf_delete(t) if t
|
175
94
|
return t
|
176
95
|
end
|
177
96
|
end
|
178
|
-
|
97
|
+
Log.debug "#{self.class}#hrf_get: no item for rank=#{rank} @count=#{@count.inspect}"
|
179
98
|
nil
|
180
99
|
end
|
181
100
|
|
182
|
-
def pop_last_rank(r,host_info)
|
183
|
-
i_tried =
|
184
|
-
|
185
|
-
tw =
|
186
|
-
if tw.rank == r
|
101
|
+
def pop_last_rank(r, host_info)
|
102
|
+
i_tried = nil
|
103
|
+
size.times do |i|
|
104
|
+
tw = q_at(i)
|
105
|
+
if tw.rank == r && tw.acceptable_for(host_info)
|
187
106
|
if tw.tried_host?(host_info)
|
188
|
-
i_tried
|
189
|
-
|
190
|
-
|
107
|
+
i_tried ||= i
|
108
|
+
else
|
109
|
+
Log.debug "#{self.class}: task=#{tw.name} i=#{i}/#{size} rank=#{tw.rank}"
|
110
|
+
return q_delete_at(i)
|
191
111
|
end
|
192
112
|
end
|
193
113
|
end
|
194
|
-
i_tried
|
195
|
-
tw =
|
196
|
-
|
197
|
-
|
198
|
-
end
|
114
|
+
if i_tried
|
115
|
+
tw = q_at(i_tried)
|
116
|
+
Log.debug "#{self.class}(retry): task=#{tw.name} i=#{i_tried}/#{size} rank=#{tw.rank}"
|
117
|
+
return q_delete_at(i_tried)
|
199
118
|
end
|
200
119
|
nil
|
201
120
|
end
|
202
121
|
|
203
122
|
def hrf_delete(t)
|
204
|
-
@count[t.rank] -=
|
205
|
-
end
|
206
|
-
|
207
|
-
def check(t=nil)
|
208
|
-
sum = 0
|
209
|
-
@count.each{|x| sum+=x if x}
|
210
|
-
if size != sum
|
211
|
-
#$stderr.puts self.inspect
|
212
|
-
#$stderr.puts t.inspect if t
|
213
|
-
raise "sise != @count.sum"
|
214
|
-
end
|
123
|
+
@count[t.rank] -= t.use_cores(@nproc)
|
215
124
|
end
|
216
125
|
end
|
217
126
|
|
127
|
+
|
218
128
|
# LIFO + HRF
|
219
129
|
class LifoHrfQueueArray
|
220
130
|
include HrfQueue
|
221
131
|
extend Forwardable
|
222
|
-
def_delegators :@a, :empty?, :size, :first, :last, :
|
132
|
+
def_delegators :@a, :empty?, :size, :first, :last, :q_at, :q_delete_at, :find_rank
|
223
133
|
|
224
|
-
def initialize(
|
225
|
-
@a = LifoQueueArray.new
|
226
|
-
hrf_init(
|
134
|
+
def initialize(nproc)
|
135
|
+
@a = LifoQueueArray.new(nproc)
|
136
|
+
hrf_init(nproc)
|
227
137
|
end
|
228
138
|
|
229
139
|
def push(t)
|
@@ -231,9 +141,9 @@ module Pwrake
|
|
231
141
|
hrf_push(t)
|
232
142
|
end
|
233
143
|
|
234
|
-
def shift(host_info
|
144
|
+
def shift(host_info, rank)
|
235
145
|
return nil if empty?
|
236
|
-
hrf_get(host_info)
|
146
|
+
hrf_get(host_info, rank)
|
237
147
|
end
|
238
148
|
|
239
149
|
def delete(t)
|
@@ -243,155 +153,8 @@ module Pwrake
|
|
243
153
|
x
|
244
154
|
end
|
245
155
|
|
246
|
-
def pop_super(host_info)
|
247
|
-
@a.shift(host_info)
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
|
252
|
-
# Priority + HRF
|
253
|
-
class PriorityHrfQueueArray < PriorityQueueArray
|
254
|
-
include HrfQueue
|
255
|
-
|
256
|
-
def initialize(n)
|
257
|
-
super(n)
|
258
|
-
hrf_init(n)
|
259
|
-
end
|
260
|
-
|
261
|
-
def push(t)
|
262
|
-
super(t)
|
263
|
-
hrf_push(t)
|
264
|
-
end
|
265
|
-
|
266
|
-
def shift
|
267
|
-
return nil if empty?
|
268
|
-
hrf_get
|
269
|
-
end
|
270
|
-
|
271
|
-
def pop_super
|
272
|
-
pop
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
|
277
|
-
# Rank-Even Last In First Out
|
278
|
-
class RankQueueArray
|
279
|
-
|
280
|
-
def initialize(n)
|
281
|
-
@q = []
|
282
|
-
@size = 0
|
283
|
-
@n = (n>0) ? n : 1
|
284
|
-
end
|
285
|
-
|
286
|
-
def push(t)
|
287
|
-
r = t ? t.rank : 0
|
288
|
-
a = @q[r]
|
289
|
-
if a.nil?
|
290
|
-
@q[r] = a = []
|
291
|
-
end
|
292
|
-
@size += 1
|
293
|
-
a.push(t)
|
294
|
-
end
|
295
|
-
|
296
|
-
def size
|
297
|
-
@size
|
298
|
-
end
|
299
|
-
|
300
|
-
def empty?
|
301
|
-
@size == 0
|
302
|
-
end
|
303
|
-
|
304
|
-
def shift
|
305
|
-
if empty?
|
306
|
-
return nil
|
307
|
-
end
|
308
|
-
(@q.size-1).downto(0) do |i|
|
309
|
-
a = @q[i]
|
310
|
-
next if a.nil? || a.empty?
|
311
|
-
@size -= 1
|
312
|
-
if a.size <= @n
|
313
|
-
return pop_last_max(a)
|
314
|
-
else
|
315
|
-
return shift_weighted
|
316
|
-
end
|
317
|
-
end
|
318
|
-
raise "ELIFO: @q=#{@q.inspect}"
|
319
|
-
end
|
320
|
-
|
321
|
-
def shift_weighted
|
322
|
-
weight, weight_avg = RANK_STAT.rank_weight
|
323
|
-
wsum = 0.0
|
324
|
-
q = []
|
325
|
-
@q.each_with_index do |a,i|
|
326
|
-
next if a.nil? || a.empty?
|
327
|
-
w = weight[i]
|
328
|
-
w = weight_avg if w.nil?
|
329
|
-
# w *= a.size
|
330
|
-
wsum += w
|
331
|
-
q << [a,wsum]
|
332
|
-
end
|
333
|
-
#
|
334
|
-
x = rand() * wsum
|
335
|
-
Log.debug "shift_weighted x=#{x} wsum=#{wsum} weight=#{weight.inspect}"
|
336
|
-
q.each do |a,w|
|
337
|
-
if w > x
|
338
|
-
return a.pop
|
339
|
-
end
|
340
|
-
end
|
341
|
-
raise "ELIFO: wsum=#{wsum} x=#{x}"
|
342
|
-
end
|
343
|
-
|
344
|
-
def pop_last_max(a)
|
345
|
-
if a.size < 2
|
346
|
-
return a.pop
|
347
|
-
end
|
348
|
-
y_max = nil
|
349
|
-
i_max = nil
|
350
|
-
n = [@n, a.size].min
|
351
|
-
(-n..-1).each do |i|
|
352
|
-
y = a[i].input_file_size
|
353
|
-
if y_max.nil? || y > y_max
|
354
|
-
y_max = y
|
355
|
-
i_max = i
|
356
|
-
end
|
357
|
-
end
|
358
|
-
a.delete_at(i_max)
|
359
|
-
end
|
360
|
-
|
361
|
-
def first
|
362
|
-
return nil if empty?
|
363
|
-
@q.size.times do |i|
|
364
|
-
a = @q[i]
|
365
|
-
unless a.nil? || a.empty?
|
366
|
-
return a.first
|
367
|
-
end
|
368
|
-
end
|
369
|
-
end
|
370
|
-
|
371
|
-
def last
|
372
|
-
return nil if empty?
|
373
|
-
@q.size.times do |i|
|
374
|
-
a = @q[-i-1]
|
375
|
-
unless a.nil? || a.empty?
|
376
|
-
return a.last
|
377
|
-
end
|
378
|
-
end
|
379
|
-
end
|
380
|
-
|
381
|
-
def delete(t)
|
382
|
-
n = 0
|
383
|
-
@q.each do |a|
|
384
|
-
if a
|
385
|
-
a.delete(t)
|
386
|
-
n += a.size
|
387
|
-
end
|
388
|
-
end
|
389
|
-
@size = n
|
390
|
-
end
|
391
|
-
|
392
|
-
def clear
|
393
|
-
@q.clear
|
394
|
-
@size = 0
|
156
|
+
def pop_super(host_info, rank)
|
157
|
+
@a.shift(host_info, rank)
|
395
158
|
end
|
396
159
|
end
|
397
160
|
|