pwrake 2.2.9 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 PriorityQueueArray < Array
7
- def initialize(n)
8
- super()
9
- end
10
-
11
- def shift
12
- pop
13
- end
6
+ class QueueArray < Array
14
7
 
15
- def push(t)
16
- priority = t.priority
17
- if empty? || last.priority <= priority
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 index(t)
37
- if size < 40
38
- return super(t)
39
- end
40
- priority = t.priority
41
- if last.priority < priority || first.priority > priority
42
- nil
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
- upper = mid
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
- end
61
- end # PriorityQueueArray
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
- class FifoQueueArray < Array
91
- def initialize(n_cores=nil)
92
- super()
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
- i_tried.each do |i|
107
- tw = at(i)
108
- if tw.acceptable_for(host_info)
109
- return delete_at(i)
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
- nil
48
+ count.size - 1
113
49
  end
114
- end
115
50
 
116
- class RankCounter
51
+ end
117
52
 
118
- def initialize
119
- @ntask = []
120
- @nproc = 0
121
- @mutex = Mutex.new
53
+ class LifoQueueArray < QueueArray
54
+ def q_at(i)
55
+ at(size-1-i)
122
56
  end
123
-
124
- def add_nproc(n)
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
- def incr(r)
131
- @mutex.synchronize do
132
- @ntask[r] = (@ntask[r]||0) + 1
133
- end
62
+ class FifoQueueArray < QueueArray
63
+ def q_at(i)
64
+ at(i)
134
65
  end
135
-
136
- def get_task
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(n_cores=nil)
159
- @nproc = n_cores || 0
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
- c = @count[r]
166
- @count[r] = (c) ? c+1 : 1
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(0) do |r|
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) ? pop_last_rank(r,host_info) : pop_super(host_info)
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
- raise "no element"
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
- (size-1).downto(0) do |i|
185
- tw = at(i)
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 << i
189
- elsif tw.acceptable_for(host_info)
190
- return delete_at(i)
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.each do |i|
195
- tw = at(i)
196
- if tw.acceptable_for(host_info)
197
- return delete_at(i)
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] -= 1
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, :at, :delete_at
132
+ def_delegators :@a, :empty?, :size, :first, :last, :q_at, :q_delete_at, :find_rank
223
133
 
224
- def initialize(n_cores)
225
- @a = LifoQueueArray.new
226
- hrf_init(n_cores)
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=nil)
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