pwrake 0.9.9 → 0.9.9.2

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.
@@ -48,6 +48,8 @@ module Pwrake
48
48
  'NUM_NOACTION_THREADS', # default=4 when gfarm, else 1
49
49
  'STEAL_WAIT',
50
50
  'STEAL_WAIT_MAX',
51
+ 'GRAPH_PARTITION',
52
+ 'PLOT_PARTITION',
51
53
 
52
54
  ['HOSTFILE','HOSTS'],
53
55
  ['LOGFILE','LOG',
@@ -108,7 +110,6 @@ module Pwrake
108
110
  # ----- init -----
109
111
 
110
112
  def init_option
111
- @host_group = []
112
113
  init_options
113
114
  init_pass_env
114
115
  init_logger
@@ -127,7 +128,7 @@ module Pwrake
127
128
  @counter = Counter.new
128
129
  end
129
130
 
130
- attr_reader :core_list
131
+ attr_reader :host_list
131
132
  attr_reader :counter
132
133
  attr_reader :logfile
133
134
  attr_reader :queue_class
@@ -312,53 +313,10 @@ module Pwrake
312
313
  if @hostfile && @num_threads
313
314
  raise "Cannot set `hostfile' and `num_threads' simultaneously"
314
315
  end
315
- if @hostfile
316
- require "socket"
317
- tmplist = []
318
- File.open(@hostfile) do |f|
319
- re = /\[\[([\w\d]+)-([\w\d]+)\]\]/o
320
- while l = f.gets
321
- l = $1 if /^([^#]*)#/ =~ l
322
- host, ncore, group = l.split
323
- if host
324
- if re =~ host
325
- hosts = ($1..$2).map{|i| host.sub(re,i)}
326
- else
327
- hosts = [host]
328
- end
329
- hosts.each do |host|
330
- begin
331
- host = Socket.gethostbyname(host)[0]
332
- rescue
333
- Log.info "-- FQDN not resoved : #{host}"
334
- end
335
- ncore = (ncore || 1).to_i
336
- group = (group || 0).to_i
337
- tmplist << ([host] * ncore.to_i)
338
- @host_group[group] ||= []
339
- @host_group[group] << host
340
- end
341
- end
342
- end
343
- end
344
- #
345
- @core_list = []
346
- begin # alternative order
347
- sz = 0
348
- tmplist.each do |a|
349
- @core_list << a.shift if !a.empty?
350
- sz += a.size
351
- end
352
- end while sz>0
353
- @num_threads = @core_list.size
354
- else
355
- @num_threads = 1 if !@num_threads
356
- @core_list = ['localhost'] * @num_threads
357
- end
358
- Log.info "num_cores=#{@core_list.size}"
316
+ @host_list = HostList.new(@hostfile || @num_threads)
317
+ Log.info "num_cores=#{@host_list.size}"
359
318
  end
360
319
 
361
-
362
320
  def set_filesystem
363
321
  if fn = @opts["PROFILE"]
364
322
  Shell.profiler.open(fn,@opts['GNU_TIME'],@opts['PLOT_PARALLELISM'])
@@ -397,7 +355,7 @@ module Pwrake
397
355
  else
398
356
  @queue_class = LocalityAwareQueue
399
357
  end
400
- @num_noaction_threads = (n_noaction_th || [8,@num_threads].max).to_i
358
+ @num_noaction_threads = (n_noaction_th || [8,@host_list.num_threads].max).to_i
401
359
  @postprocess = GfarmPostprocess.new
402
360
  Log.debug "--- @queue_class=#{@queue_class}"
403
361
  else
@@ -48,7 +48,14 @@ EOL
48
48
  end
49
49
  end
50
50
 
51
- @sh_table = CSV.read(@csv_file,:headers=>true)
51
+ begin
52
+ @sh_table = CSV.read(@csv_file,:headers=>true)
53
+ rescue
54
+ $stderr.puts "error in reading "+@csv_file
55
+ $stderr.puts $!, $@
56
+ exit
57
+ end
58
+
52
59
  h = {}
53
60
  @elap_sum = 0
54
61
  @sh_table.each do |row|
@@ -294,7 +301,13 @@ set title 'histogram of elapsed time'"
294
301
  class TaskStat
295
302
 
296
303
  def initialize(task_file, sh_table)
297
- @task_table = CSV.read(task_file,:headers=>true)
304
+ begin
305
+ @task_table = CSV.read(task_file,:headers=>true)
306
+ rescue
307
+ $stderr.puts "error in reading "+task_file
308
+ $stderr.puts $!, $@
309
+ exit
310
+ end
298
311
  @count = Hash.new(0)
299
312
  task_locality
300
313
  stat_sh_table(sh_table)
@@ -55,6 +55,26 @@ module Pwrake
55
55
 
56
56
  def location=(a)
57
57
  @location = a
58
+ @group = []
59
+ @location.each do |host|
60
+ @group |= [Pwrake.application.host_list.host2group[host]]
61
+ end
62
+ end
63
+
64
+ def group
65
+ @group ||= []
66
+ end
67
+
68
+ def group_id
69
+ @group_id
70
+ end
71
+
72
+ def group_id=(i)
73
+ @group_id = i
74
+ end
75
+
76
+ def suggest_location=(a)
77
+ @suggest_location = a
58
78
  end
59
79
 
60
80
  def task_id
@@ -64,6 +84,11 @@ module Pwrake
64
84
  def invoke_modify(*args)
65
85
  return if @already_invoked
66
86
 
87
+ if Pwrake.application.pwrake_options['GRAPH_PARTITION']
88
+ require 'pwrake/mcgp'
89
+ MCGP.graph_partition
90
+ end
91
+
67
92
  application.start_worker
68
93
 
69
94
  if false
@@ -141,6 +166,10 @@ module Pwrake
141
166
  Log.debug "--- pw_invoke (#{name}) enq_subseq time=#{Time.now-t} sec"
142
167
  end
143
168
 
169
+ def get_file_stat
170
+ @file_stat ||= File::Stat.new(name)
171
+ end
172
+
144
173
  def log_task(time_start)
145
174
  time_end = Time.now
146
175
 
@@ -391,6 +420,29 @@ module Pwrake
391
420
  @suggest_location
392
421
  end
393
422
 
423
+ def priority
424
+ if has_input_file? && @priority.nil?
425
+ sum_tm = 0
426
+ sum_sz = 0
427
+ @prerequisites.each do |preq|
428
+ pq = application[preq]
429
+ sz = pq.file_size
430
+ if sz > 0
431
+ tm = pq.file_mtime - START_TIME
432
+ sum_tm += tm * sz
433
+ sum_sz += sz
434
+ end
435
+ end
436
+ if sum_sz > 0
437
+ @priority = sum_tm / sum_sz
438
+ else
439
+ @priority = 0
440
+ end
441
+ Log.debug "--- task_name=#{name} priority=#{@priority} sum_file_size=#{sum_sz}"
442
+ end
443
+ @priority || 0
444
+ end
445
+
394
446
  def input_file_mtime
395
447
  if has_input_file? && @input_file_mtime.nil?
396
448
  hash = Hash.new
@@ -418,25 +470,6 @@ module Pwrake
418
470
  @input_file_mtime
419
471
  end
420
472
 
421
- def suggest_location2
422
- if kind_of?(Rake::FileTask) && preq_name = @prerequisites[0]
423
- application[preq_name].location
424
- end
425
- end
426
-
427
- def log_host(exec_host)
428
- # exec_host = Pwrake.current_shell.host
429
- if loc = suggest_location()
430
- Pwrake.application.count( loc, exec_host )
431
- if loc.include? exec_host
432
- compare = "=="
433
- else
434
- compare = "!="
435
- end
436
- Log.info "-- access to #{@prerequisites[0]}: file_host=#{loc.inspect} #{compare} exec_host=#{exec_host}"
437
- end
438
- end
439
-
440
473
  end
441
474
 
442
475
  end # module Pwrake
@@ -12,18 +12,22 @@ module Pwrake
12
12
  super()
13
13
  end
14
14
 
15
+ def shift
16
+ pop
17
+ end
18
+
15
19
  def push(t)
16
- task_id = t.task_id
17
- if empty? || last.task_id <= task_id
20
+ priority = t.priority
21
+ if empty? || last.priority <= priority
18
22
  super(t)
19
- elsif first.task_id > task_id
23
+ elsif first.priority > priority
20
24
  unshift(t)
21
25
  else
22
26
  lower = 0
23
27
  upper = size-1
24
28
  while lower+1 < upper
25
29
  mid = ((lower + upper) / 2).to_i
26
- if self[mid].task_id <= task_id
30
+ if self[mid].priority <= priority
27
31
  lower = mid
28
32
  else
29
33
  upper = mid
@@ -37,23 +41,23 @@ module Pwrake
37
41
  if size < 40
38
42
  return super(t)
39
43
  end
40
- task_id = t.task_id
41
- if last.task_id < task_id || first.task_id > task_id
44
+ priority = t.priority
45
+ if last.priority < priority || first.priority > priority
42
46
  nil
43
47
  else
44
48
  lower = 0
45
49
  upper = size-1
46
50
  while lower+1 < upper
47
51
  mid = ((lower + upper) / 2).to_i
48
- if self[mid].task_id < task_id
52
+ if self[mid].priority < priority
49
53
  lower = mid
50
54
  else
51
55
  upper = mid
52
56
  end
53
57
  end
54
58
  mid = upper
55
- if self[mid].task_id == task_id
56
- Log.debug "--- TQA#index=#{mid}, task_id=#{task_id}"
59
+ if self[mid].priority == priority
60
+ Log.debug "--- TQA#index=#{mid}, priority=#{priority}"
57
61
  mid
58
62
  end
59
63
  end
@@ -78,39 +82,79 @@ module Pwrake
78
82
  end
79
83
  end
80
84
 
85
+ class RankCounter
81
86
 
82
- # LIFO + HRF
83
- class LifoHrfQueueArray < Array
84
- def initialize(n)
85
- @n = (n>0) ? n : 1
86
- @count = []
87
+ def initialize
88
+ @ntask = []
89
+ @nproc = 0
90
+ @mutex = Mutex.new
87
91
  end
88
92
 
89
- def push(t)
90
- super(t)
91
- r = t.rank
92
- @count[r] = (@count[r]||0) + 1
93
+ def add_nproc(n)
94
+ @mutex.synchronize do
95
+ @nproc += n
96
+ end
93
97
  end
94
98
 
95
- def shift
96
- if empty?
97
- return nil
99
+ def incr(r)
100
+ @mutex.synchronize do
101
+ @ntask[r] = (@ntask[r]||0) + 1
98
102
  end
103
+ end
104
+
105
+ def get_task
106
+ @mutex.synchronize do
107
+ (@ntask.size-1).downto(0) do |r|
108
+ c = @ntask[r]
109
+ if c && c>0
110
+ t = yield(c, @nproc, r)
111
+ #t = (c<=@n) ? pop_last_rank(r) : pop
112
+ if t
113
+ @ntask[t.rank] -= 1
114
+ Log.debug "--- RankCount rank=#{r} nproc=#{@nproc} count=#{c} t.rank=#{t.rank} t.name=#{t.name}"
115
+ end
116
+ return t
117
+ end
118
+ end
119
+ end
120
+ nil
121
+ end
122
+ end
123
+
124
+ # HRF mixin module
125
+ module HrfQueue
126
+
127
+ def hrf_init(n=nil)
128
+ @nproc = n || 0
129
+ @count = []
130
+ end
131
+
132
+ def hrf_push(t)
133
+ if t
134
+ r = t.rank
135
+ @count[r] = (@count[r]||0) + 1
136
+ end
137
+ end
138
+
139
+ def hrf_get
99
140
  (@count.size-1).downto(0) do |r|
100
141
  c = @count[r]
101
142
  if c && c>0
102
- t = (c<=@n) ? pop_last_rank(r) : pop
103
- @count[t.rank] -= 1
143
+ t = (c <= @nproc) ? pop_last_rank(r) : pop_super
144
+ if t
145
+ @count[t.rank] -= 1
146
+ end
104
147
  return t
105
148
  end
106
149
  end
150
+ raise "no element"
107
151
  nil
108
152
  end
109
153
 
110
154
  def pop_last_rank(r)
111
155
  (size-1).downto(0) do |i|
112
156
  t = at(i)
113
- if t.rank == r
157
+ if t && t.rank == r
114
158
  delete_at(i)
115
159
  return t
116
160
  end
@@ -119,9 +163,58 @@ module Pwrake
119
163
  end
120
164
  end
121
165
 
166
+ # LIFO + HRF
167
+ class LifoHrfQueueArray < Array
168
+ include HrfQueue
169
+
170
+ def initialize(n)
171
+ super()
172
+ hrf_init(n)
173
+ end
174
+
175
+ def push(t)
176
+ super(t)
177
+ hrf_push(t)
178
+ end
179
+
180
+ def shift
181
+ return nil if empty?
182
+ hrf_get
183
+ end
184
+
185
+ def pop_super
186
+ pop
187
+ end
188
+ end
189
+
190
+ # Priority + HRF
191
+ class PriorityHrfQueueArray < PriorityQueueArray
192
+ include HrfQueue
193
+
194
+ def initialize(n)
195
+ super(n)
196
+ hrf_init(n)
197
+ end
198
+
199
+ def push(t)
200
+ super(t)
201
+ hrf_push(t)
202
+ end
203
+
204
+ def shift
205
+ return nil if empty?
206
+ hrf_get
207
+ end
208
+
209
+ def pop_super
210
+ pop
211
+ end
212
+ end
213
+
122
214
 
123
215
  # Rank-Even Last In First Out
124
216
  class RankQueueArray
217
+
125
218
  def initialize(n)
126
219
  @q = []
127
220
  @size = 0
@@ -129,7 +222,7 @@ module Pwrake
129
222
  end
130
223
 
131
224
  def push(t)
132
- r = t.rank
225
+ r = t ? t.rank : 0
133
226
  a = @q[r]
134
227
  if a.nil?
135
228
  @q[r] = a = []
@@ -362,7 +455,7 @@ module Pwrake
362
455
 
363
456
  class TaskQueue
364
457
 
365
- def initialize(core_list)
458
+ def initialize(host_list)
366
459
  @finished = false
367
460
  @halt = false
368
461
  @mutex = Mutex.new
@@ -371,7 +464,7 @@ module Pwrake
371
464
  @q_noaction = NoActionQueue.new
372
465
  pri = Pwrake.application.pwrake_options['QUEUE_PRIORITY'] || "RANK"
373
466
  case pri
374
- when /dfs/i
467
+ when /prio/i
375
468
  @array_class = PriorityQueueArray
376
469
  when /fifo/i
377
470
  @array_class = FifoQueueArray # Array # Fifo
@@ -379,18 +472,20 @@ module Pwrake
379
472
  @array_class = LifoQueueArray
380
473
  when /lihr/i
381
474
  @array_class = LifoHrfQueueArray
475
+ when /prhr/i
476
+ @array_class = PriorityHrfQueueArray
382
477
  when /rank/i
383
478
  @array_class = RankQueueArray
384
479
  else
385
480
  raise RuntimeError,"unknown option for QUEUE_PRIORITY: "+pri
386
481
  end
387
482
  Log.debug "--- TQ#initialize @array_class=#{@array_class.inspect}"
388
- init_queue(core_list)
483
+ init_queue(host_list)
389
484
  end
390
485
 
391
- def init_queue(core_list)
486
+ def init_queue(host_list)
392
487
  @cv = TaskConditionVariable.new
393
- @q_input = @array_class.new(core_list.size)
488
+ @q_input = @array_class.new(host_list.size)
394
489
  @q_later = Array.new
395
490
  end
396
491
 
@@ -476,6 +571,7 @@ module Pwrake
476
571
  @cv.signal
477
572
  return false
478
573
  end
574
+ #@cv.signal
479
575
  @cv.wait(@mutex)
480
576
  n = 0
481
577