autoflow 0.8.5 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f312d125afdd65f9895264cda8383258bd155fb3
4
- data.tar.gz: 005f0219a73e5f38811df45b30d5fdaba7f243ae
2
+ SHA256:
3
+ metadata.gz: 1e2701342ff440d0d59eb570fe27b29207d53086ba8136a7a36cf4d6645282c1
4
+ data.tar.gz: 617a0049af3be6e649947f73eabe68ac38016fd0e687b42ef1c3081faebe3db7
5
5
  SHA512:
6
- metadata.gz: 2106ec11e38495b7338bef9cf94a02f2df9a9ddaea8a464167872d4a5919ace690dfd9624ea68f60d3fde74fda5d4aab606f4905c3241eb434697b14049628f2
7
- data.tar.gz: 2f046987dd54bee1c4c256e5475c7a544ecbaf5735b4b01677f841188457fe5eaf644dcbc2d0089a0f6ea30cc0cbe4c310f333d73b6a2b673a3be8bb11755033
6
+ metadata.gz: 768d88e9b31cce325d703a27659e63485ae801701bdc4a668218df71888d4517a62be5f95c681f29828a7ef93d00a3cacf51af66e354cd4c56b0d5b415511722
7
+ data.tar.gz: e5495d58e69440871e743613716866eeb1a93968214cc50fc5da2298beb5cb3d5dadcf67bdcf0ce0ce208696740866805ba6cbfc12cce1d056e2d0ead6f44ce7
data/autoflow.gemspec CHANGED
@@ -19,10 +19,11 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_runtime_dependency 'net-ssh', '>= 2.8.0'
22
- spec.add_runtime_dependency 'git', '>= 1.3.0'
22
+ spec.add_runtime_dependency 'git', '>= 0.8.1'
23
23
  spec.add_runtime_dependency 'win32console', '>= 1.3.2' if !ENV['OS'].nil? && ENV['OS'].downcase.include?('windows')
24
- spec.add_runtime_dependency 'colorize', '~> 0.7.3'
25
- spec.add_runtime_dependency 'terminal-table', '~> 1.6.0'
26
- spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_runtime_dependency 'colorize', '>= 0.7.3'
25
+ spec.add_runtime_dependency 'terminal-table', '>= 2.0.0'
26
+ spec.add_runtime_dependency 'openssl', '>= 2.2.0'
27
+ spec.add_development_dependency "bundler", ">= 2.2.7"
27
28
  spec.add_development_dependency "rake"
28
29
  end
data/bin/AutoFlow CHANGED
@@ -83,6 +83,11 @@ optparse = OptionParser.new do |opts|
83
83
  options[:add] = add
84
84
  end
85
85
 
86
+ options[:additional_job_options] = nil
87
+ opts.on( '-A', '--additional_job_options STRING', 'Additional option in queue system jobs. Format: "parameter:value"' ) do |opt|
88
+ options[:additional_job_options] = opt.split(':')
89
+ end
90
+
86
91
  options[:batch] = false
87
92
  opts.on( '-b', '--batch', 'Workflow execution using batch' ) do
88
93
  options[:batch] = true
@@ -103,6 +108,11 @@ optparse = OptionParser.new do |opts|
103
108
  options[:external_dependencies] = external_dependencies.split(',')
104
109
  end
105
110
 
111
+ options[:extended_logging] = false
112
+ opts.on( '-e', '--extended_logging', 'If set the command /usr/bin/time will be used instead of shell built-in version. Data will be saved in process_data file of task folder' ) do
113
+ options[:extended_logging] = true
114
+ end
115
+
106
116
  options[:retry] = false
107
117
  opts.on( '-f', '--force', 'Execute all jobs, including any job commented with %' ) do
108
118
  options[:retry] = true
data/bin/flow_logger CHANGED
@@ -296,6 +296,15 @@ OptionParser.new do |opts|
296
296
  opts.on("-H", "--html", "Make a workflow execution full report in html format") do |opt|
297
297
  options[:html] = true
298
298
  end
299
+
300
+ # Set a banner, displayed at the top of the help screen.
301
+ opts.banner = "Usage: flow_logger [options] \n\n"
302
+
303
+ # This displays the help screen
304
+ opts.on( '-h', '--help', 'Display this screen' ) do
305
+ puts opts
306
+ exit
307
+ end
299
308
  end.parse!
300
309
 
301
310
  #################################################################################################
@@ -4,14 +4,15 @@ class Batch
4
4
  @@all_batch = {}
5
5
  @@jobs_names = []
6
6
  @@batch_iterator_relations = {}
7
- @@state_iterations = {}
7
+ @@nested_iteration_relations = {}
8
8
  @@general_computation_attrib = {
9
9
  :cpu => nil,
10
10
  :mem => nil,
11
11
  :time => nil,
12
12
  :node => nil,
13
13
  :multinode => nil,
14
- :ntask => nil
14
+ :ntask => nil,
15
+ :additional_job_options => nil
15
16
  }
16
17
 
17
18
  def self.set_general_attrib(attrib_hash)
@@ -20,6 +21,7 @@ class Batch
20
21
 
21
22
 
22
23
  def initialize(tag, init, main_command, id, exec_folder)
24
+ @regex_deps = nil
23
25
  replace_regexp(tag, init, main_command)
24
26
  @name = nil
25
27
  @id = id
@@ -63,6 +65,7 @@ class Batch
63
65
  data = /!JobRegExp:([^ \n]+):([^ \n]+)!([^ \n]+)/.match(command) # *to1 with regexp
64
66
  #data[0] => reference string (command), data[1] => batch_pattern, data[2] => iterator_pattern, data[3] => adyacent string to regexp as regexp/file_name
65
67
  job_names = get_dependencies_by_regexp(data[1], data[2])
68
+ @regex_deps = 'command' if job_names.length > 0
66
69
  new_string = job_names.map{|jn| jn + ')' + data[3] }.join(' ')
67
70
  command.gsub!(data[0], new_string)
68
71
  #puts command.inspect
@@ -72,6 +75,9 @@ class Batch
72
75
  data = /JobRegExp:([^ \n]+):([^;\] \n]+)/.match(tag) # 1to1 with regexp
73
76
  #data[0] => reference string (command), data[1] => batch_pattern, data[2] => iterator_pattern
74
77
  job_names = get_dependencies_by_regexp(data[1], data[2])
78
+ if job_names.length > 0
79
+ @regex_deps = 'tag'
80
+ end
75
81
  new_string = job_names.map{|jn| jn + ')'}.join(';')
76
82
  tag.gsub!(data[0], new_string)
77
83
  end
@@ -188,6 +194,8 @@ class Batch
188
194
  @attrib[:time] = fields[index+1]
189
195
  elsif field == '-u'
190
196
  @attrib[:multinode] = fields[index+1].to_i
197
+ elsif field == '-A'
198
+ @attrib[:additional_job_options] = fields[index+1].split(':')
191
199
  end
192
200
  end
193
201
  if fields.include?('-s')
@@ -253,6 +261,7 @@ class Batch
253
261
  new_job = duplicate_job(tmp_j, iter)
254
262
  check_dependencies(new_job, iter, temp_jobs)
255
263
  parse_iter(iter, @name, new_job)
264
+ add_nested_iteration_relation(tmp_j, new_job)
256
265
  @@jobs_names << new_job.name
257
266
  jobs << new_job
258
267
  @jobs << new_job
@@ -261,6 +270,7 @@ class Batch
261
270
  end
262
271
  temp_jobs = delete_jobs(jobs2delete, temp_jobs) #Remove temporal jobs
263
272
  else
273
+ check_regex_dependencies
264
274
  @iterator.each_with_index do |iter, num|
265
275
  job_attrib = @attrib.dup
266
276
  if !iter.nil?
@@ -283,6 +293,61 @@ class Batch
283
293
  return jobs
284
294
  end
285
295
 
296
+ def add_nested_iteration_relation(tmp_j, new_job)
297
+ query = @@nested_iteration_relations[tmp_j.name]
298
+ if query.nil?
299
+ @@nested_iteration_relations[tmp_j.name] = [new_job.name]
300
+ else
301
+ query << new_job.name
302
+ end
303
+ end
304
+
305
+ def check_regex_dependencies
306
+ if @regex_deps == 'tag'
307
+ new_job_names = []
308
+ @iterator.each do |iter|
309
+ new_names = find_job_names(iter.gsub(')', ''))
310
+ new_job_names.concat(new_names)
311
+ end
312
+ @iterator = new_job_names.map{|nj| nj + ')'} if !new_job_names.empty?
313
+ elsif @regex_deps == 'command'
314
+ [@initialization, @main_command].each do |command|
315
+ patterns = command.scan(/([^\s)]+)\)([^\s]*)/)
316
+ if !patterns.empty?
317
+ patterns.each do |putative_job, sufix|
318
+ job_names = find_job_names(putative_job)
319
+ if !job_names.empty?
320
+ new_string = job_names.map{|jn| "#{jn})#{sufix}"}.join(' ')
321
+ old_string = "#{putative_job})#{sufix}"
322
+ command.gsub!(old_string, new_string)
323
+ end
324
+ end
325
+ end
326
+ end
327
+ end
328
+ end
329
+
330
+ def find_job_names(name)
331
+ final_names = []
332
+ intermediary_names = @@nested_iteration_relations[name]
333
+ if !intermediary_names.nil?
334
+ while !intermediary_names.empty?
335
+ final_names = intermediary_names
336
+ i_names = []
337
+ intermediary_names.each do |i_n|
338
+ query = @@nested_iteration_relations[i_n]
339
+ i_names.concat(query) if !query.nil?
340
+ end
341
+ if !i_names.empty?
342
+ intermediary_names = i_names
343
+ else
344
+ break
345
+ end
346
+ end
347
+ end
348
+ return final_names
349
+ end
350
+
286
351
  #tmp_j => job to set dependencies in iteration
287
352
  #iter => sufix of current iteration
288
353
  #jobs => array of jobs which has the job dependency
@@ -313,7 +378,7 @@ class Batch
313
378
  def handle_dependencies(dinamic_variables)
314
379
  [@initialization, @main_command].each do |instructions|
315
380
  if instructions.class.to_s == 'String'
316
- scan_dependencies(instructions)
381
+ #scan_dependencies(instructions) # NOT NECESSARY? REMOVED BY COLLISION CON REGEX SYSTEM. THE DINAMYC VARIABLES ARE NO USED
317
382
  dinamic_variables.concat(collect_dinamic_variables(instructions))
318
383
  @dependencies.concat(check_dependencies_with_DinVar(instructions, dinamic_variables))
319
384
  end
@@ -336,8 +401,10 @@ class Batch
336
401
  @dependencies << [name, '1to1', "!#{name}*!"]
337
402
  end
338
403
  if command.include?("!#{name}!") && !string_overlap(matched_regions, "!#{name}!", command)
339
- command =~ /!#{name}!([^ \n]+)/
340
- @dependencies << [name, '*to1', "!#{name}!", $1]
404
+ #command =~ /!#{name}!([^ \n]+)/
405
+ command.scan(/!#{name}!([^ \n]+)/).each do |string_match|
406
+ @dependencies << [name, '*to1', "!#{name}!", string_match.first]
407
+ end
341
408
  end
342
409
  local_dependencies = command.scan(/#{name}([^\( \n]+)\)/)
343
410
  local_dependencies.each do |local_dependency|
@@ -15,6 +15,7 @@ class QueueManager
15
15
  @write_sh = options[:write_sh]
16
16
  @external_dependencies = options[:external_dependencies]
17
17
  @active_jobs = []
18
+ @extended_logging = options[:extended_logging]
18
19
  end
19
20
 
20
21
  ########################################################################################
@@ -267,7 +268,12 @@ class QueueManager
267
268
 
268
269
  def write_job(job, sh_name)
269
270
  write_file(sh_name, job.initialization) if !job.initialization.nil?
270
- write_file(sh_name, 'time ' + job.parameters)
271
+ if @extended_logging
272
+ log_command = '/usr/bin/time -o process_data -v '
273
+ else
274
+ log_command = 'time '
275
+ end
276
+ write_file(sh_name, log_command + job.parameters)
271
277
  end
272
278
 
273
279
  def get_dependencies(job, id = nil)
@@ -42,10 +42,10 @@ class BashManager < QueueManager
42
42
  end
43
43
 
44
44
  def self.available?(options)
45
- return TRUE
45
+ return true
46
46
  end
47
47
 
48
48
  def self.priority
49
49
  return 0
50
50
  end
51
- end
51
+ end
@@ -1,20 +1,34 @@
1
1
  require 'queue_manager'
2
2
  class SlurmManager < QueueManager
3
+ def parse_additional_options(string, attribs)
4
+ expresions = %w[%C %T %M %N ]
5
+ values = [attribs[:cpu], attribs[:time], attribs[:mem], attribs[:node]]
6
+ new_string = string.dup
7
+ expresions.each_with_index do |exp, i|
8
+ new_string.gsub!(exp, "#{values[i]}")
9
+ end
10
+ return new_string
11
+ end
12
+
3
13
  def write_header(id, job, sh_name)
4
14
  if !job.attrib[:ntask]
5
15
  write_file(sh_name, "#SBATCH --cpus=#{job.attrib[:cpu]}")
6
16
  else
7
17
  write_file(sh_name, "#SBATCH --ntasks=#{job.attrib[:cpu]}")
8
18
  write_file(sh_name, "#SBATCH --nodes=#{job.attrib[:multinode]}") if job.attrib[:multinode] > 0
9
- write_file(sh_name, 'srun hostname -s > workers') if job.attrib[:cpu_asign] == 'list'
10
19
  end
11
20
  write_file(sh_name, "#SBATCH --mem=#{job.attrib[:mem]}")
12
21
  write_file(sh_name, "#SBATCH --time=#{job.attrib[:time]}")
13
22
  write_file(sh_name, "#SBATCH --constraint=#{job.attrib[:node]}") if !job.attrib[:node].nil?
14
23
  write_file(sh_name, '#SBATCH --error=job.%J.err')
15
24
  write_file(sh_name, '#SBATCH --output=job.%J.out')
25
+ write_file(sh_name, "#SBATCH --#{job.attrib[:additional_job_options][0]}=#{parse_additional_options(job.attrib[:additional_job_options][1], job.attrib)}") if !job.attrib[:additional_job_options].nil?
26
+ if job.attrib[:ntask]
27
+ write_file(sh_name, 'srun hostname -s > workers') if job.attrib[:cpu_asign] == 'list'
28
+ end
16
29
  end
17
30
 
31
+
18
32
  def submit_job(job, ar_dependencies)
19
33
  final_dep = get_all_deps(ar_dependencies)
20
34
  dependencies = nil
@@ -34,13 +48,13 @@ class SlurmManager < QueueManager
34
48
  end
35
49
 
36
50
  def self.available?(options)
37
- available = TRUE
51
+ available = true
38
52
  shell_output = system_call("type 'sbatch'", nil, options[:remote], options[:ssh])
39
- available = FALSE if shell_output.empty?
53
+ available = false if shell_output.empty?
40
54
  return available
41
55
  end
42
56
 
43
57
  def self.priority
44
58
  return 100
45
59
  end
46
- end
60
+ end
@@ -16,7 +16,8 @@ class Stack
16
16
  :time => options[:time],
17
17
  :node => options[:node_type],
18
18
  :multinode => options[:use_multinode],
19
- :ntask => options[:use_ntasks]
19
+ :ntask => options[:use_ntasks],
20
+ :additional_job_options => options[:additional_job_options]
20
21
  })
21
22
  @@folder_name = :program_name
22
23
  @@folder_name = :job_name if options[:key_name]
@@ -76,8 +77,10 @@ class Stack
76
77
  line.gsub!(/\s/,'')
77
78
  pairs = line.split(',')
78
79
  pairs.each do |pair|
79
- pair =~ /(.+)=(.+)/
80
- variable_type[$1] = $2
80
+ #pair =~ /(.+)=(.+)/
81
+ #variable_type[$1] = $2
82
+ var, value = pair.split('=', 2)
83
+ variable_type[var] = value
81
84
  end
82
85
  end
83
86
  end
@@ -297,7 +300,7 @@ class Stack
297
300
  end
298
301
  file.puts '}'
299
302
  file.close
300
- system('dot -Tpng '+name+representation_type+'.dot -o '+name+representation_type+'.png')
303
+ system('dot -Tpdf '+name+representation_type+'.dot -o '+name+representation_type+'.pdf')
301
304
  end
302
305
 
303
306
  end
@@ -1,3 +1,3 @@
1
1
  module Autoflow
2
- VERSION = "0.8.5"
2
+ VERSION = "0.9.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autoflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.5
4
+ version: 0.9.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pedro Seoane
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-30 00:00:00.000000000 Z
11
+ date: 2021-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-ssh
@@ -30,56 +30,70 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.3.0
33
+ version: 0.8.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 1.3.0
40
+ version: 0.8.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: colorize
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 0.7.3
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.7.3
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: terminal-table
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 1.6.0
61
+ version: 2.0.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 1.6.0
68
+ version: 2.0.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: openssl
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 2.2.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 2.2.0
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: bundler
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - "~>"
87
+ - - ">="
74
88
  - !ruby/object:Gem::Version
75
- version: '1.3'
89
+ version: 2.2.7
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - "~>"
94
+ - - ">="
81
95
  - !ruby/object:Gem::Version
82
- version: '1.3'
96
+ version: 2.2.7
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rake
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -131,7 +145,7 @@ homepage: ''
131
145
  licenses:
132
146
  - MIT
133
147
  metadata: {}
134
- post_install_message:
148
+ post_install_message:
135
149
  rdoc_options: []
136
150
  require_paths:
137
151
  - lib
@@ -146,9 +160,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
160
  - !ruby/object:Gem::Version
147
161
  version: '0'
148
162
  requirements: []
149
- rubyforge_project:
150
- rubygems_version: 2.4.8
151
- signing_key:
163
+ rubygems_version: 3.2.3
164
+ signing_key:
152
165
  specification_version: 4
153
166
  summary: '"This gem take a pipeline and launch it on a queue system"'
154
167
  test_files: