autoflow 0.8.5 → 0.9.6

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
- 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: