rbbt-util 5.32.18 → 5.32.23

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
2
  SHA256:
3
- metadata.gz: adee22216a6bbce0a4292f20e89f3c620fc47fcb28aaaf15082cd3ee54d2c093
4
- data.tar.gz: 920f61f95dce1acbecc279ae09731dab297d0eb57cffe7a08734297e917436f8
3
+ metadata.gz: 900a7061d40ec2cbffd38886ef9629aa0c0ed6d6ee1aef6e0c95c51656230ef0
4
+ data.tar.gz: 13b965a0ec134a932c6ae0ae6a109fbc2bc83b7ffd855a1ef05ed4e1e51b9d88
5
5
  SHA512:
6
- metadata.gz: f7fb0024e458db313ab31a46c4142092121d76efc5ca79c85876a8dc412e6483c12cf3058a1f9f5e6300a31ce672e87b60864eff46c2af8662df411e5680ac39
7
- data.tar.gz: 4216a058f4329d25ed573129c0b40408921566218267922f1b3831108ab2745fc36279fdf7ecedd580d71c0163fae44a8d36adfc2223fecad76ac5864ce90c5f
6
+ metadata.gz: 3b890e2b6fb3675df4319d0541d9057a54b0cb37286a814822915f5b5b061d4f7e02deab0afdd7cd0833cb741aeded7454a9585f93ff3486e595b99db4da00f6
7
+ data.tar.gz: 105072ca6c7b5c43c6a60455eaa9c7167feeb93f505c61c6aeffe6305de3166a6cb440c262abf025407306ba82c2fe3167f5f9e743e086d99fa936e44ea8e448
@@ -44,6 +44,7 @@ export BATCH_SYSTEM=SLURM
44
44
  time = Misc.format_seconds Misc.timespan(time) unless time.include? ":"
45
45
 
46
46
  sbatch_params = {"job-name" => batch_name,
47
+ "qos" => queue,
47
48
  "output" => fout,
48
49
  "error" => ferr,
49
50
  "cpus-per-task" => task_cpus,
@@ -133,7 +133,7 @@ module TSV
133
133
  []
134
134
  else
135
135
  parts.values_at *field_positions
136
- end.collect{|value| value.nil? ? [] : value.split(@sep2, -1) }
136
+ end.collect{|value| (value.empty? || value.nil?) ? [nil] : value.split(@sep2, -1) }
137
137
  [keys, values]
138
138
  end
139
139
 
@@ -122,7 +122,12 @@ module Rbbt::Config
122
122
  Log.debug "Value #{value.inspect} for config key '#{ key }': #{tokens * ", "}"
123
123
  GOT_KEYS << [key, value, tokens]
124
124
 
125
- value
125
+ if String === value && m = value.match(/^env:(.*)/)
126
+ variable = m.captures.first
127
+ ENV[variable]
128
+ else
129
+ value
130
+ end
126
131
  end
127
132
 
128
133
  def self.with_config
@@ -172,50 +172,6 @@ module Workflow
172
172
  }.tap{|h| IndiferentHash.setup(h)}
173
173
  end
174
174
 
175
- def assign_dep_inputs(_inputs, options, all_d, task_info)
176
- IndiferentHash.setup(_inputs)
177
-
178
- options.each{|i,v|
179
- next if i == :compute or i == "compute"
180
- case v
181
- when :compute
182
- compute = v
183
- when Symbol
184
- rec_dependency = all_d.flatten.select{|d| d.task_name.to_sym == v }.first
185
-
186
- if rec_dependency.nil?
187
- if _inputs.include?(v)
188
- #_inputs[i] = _inputs.delete(v)
189
- _inputs[i] = _inputs[v] unless _inputs.include? i #_inputs.delete(v)
190
- else
191
- _inputs[i] = v unless _inputs.include? i
192
- end
193
- else
194
- input_options = task_info[:input_options][i] || {}
195
-
196
- #ToDo why was this always true?
197
- if input_options[:stream] or true
198
- #rec_dependency.run(true).grace unless rec_dependency.done? or rec_dependency.running?
199
- _inputs[i] = rec_dependency
200
- else
201
- rec_dependency.abort if rec_dependency.streaming? and not rec_dependency.running?
202
- rec_dependency.clean if rec_dependency.error? or rec_dependency.aborted?
203
- if rec_dependency.streaming? and rec_dependency.running?
204
- _inputs[i] = rec_dependency.join.load
205
- else
206
- rec_dependency.run(true)
207
- rec_dependency.join
208
- _inputs[i] = rec_dependency.load
209
- end
210
- end
211
- end
212
- else
213
- _inputs[i] = v
214
- end
215
- } if options
216
-
217
- _inputs
218
- end
219
175
 
220
176
  def task_from_dep(dep)
221
177
  task = case dep
@@ -77,15 +77,15 @@ module Workflow
77
77
  returns workflow.tasks[oname].result_description if workflow.tasks.include?(oname) unless @result_description
78
78
  task name do
79
79
  raise RbbtException, "dependency not found in dep_task" if dependencies.empty?
80
- Step.wait_for_jobs dependencies
80
+ Step.wait_for_jobs dependencies.select{|d| d.streaming? }
81
81
  dep = dependencies.last
82
82
  dep.join
83
83
  raise dep.get_exception if dep.error?
84
84
  raise Aborted, "Aborted dependency #{dep.path}" if dep.aborted?
85
85
  set_info :result_type, dep.info[:result_type]
86
- forget = config :forget_dep_tasks, "forget_dep_tasks", "key:forget_dep_tasks", :default => FORGET_DEP_TASKS
86
+ forget = config :forget_dep_tasks, "forget_dep_tasks", :default => FORGET_DEP_TASKS
87
87
  if forget
88
- remove = config :remove_dep_tasks, "remove_dep_tasks", "key:remove_dep_tasks", :default => REMOVE_DEP_TASKS
88
+ remove = config :remove_dep_tasks, "remove_dep_tasks", :default => REMOVE_DEP_TASKS
89
89
 
90
90
  self.archive_deps
91
91
  self.copy_files_dir
@@ -93,15 +93,17 @@ module Workflow
93
93
  Open.rm_rf self.files_dir if Open.exist? self.files_dir
94
94
  FileUtils.cp_r dep.files_dir, self.files_dir if Open.exist?(dep.files_dir)
95
95
  Open.ln_h dep.path, self.tmp_path
96
+
96
97
  case remove.to_s
97
98
  when 'true'
98
99
  dep.clean
99
100
  when 'recursive'
100
- dep.rec_dependencies.each do |d|
101
+ (dep.dependencies + dep.rec_dependencies).uniq.each do |d|
102
+ next if d.overriden
101
103
  d.clean unless config(:remove_dep, d.task_signature, d.task_name, d.workflow.to_s, :default => true).to_s == 'false'
102
104
  end
103
105
  dep.clean unless config(:remove_dep, dep.task_signature, dep.task_name, dep.workflow.to_s, :default => true).to_s == 'false'
104
- end
106
+ end unless dep.overriden
105
107
  else
106
108
  if Open.exists?(dep.files_dir)
107
109
  Open.rm_rf self.files_dir
@@ -71,7 +71,7 @@ module Workflow
71
71
 
72
72
  def setup_override_dependency(dep, workflow, task_name)
73
73
  return [] if dep == :skip || dep == 'skip'
74
- dep = Step === dep ? dep : Workflow.load_step(dep)
74
+ dep = Step === dep ? dep.dup : Workflow.load_step(dep)
75
75
  dep.workflow = workflow
76
76
  dep.info[:name] = dep.name
77
77
  dep.original_task_name ||= dep.task_name if dep.workflow
@@ -83,14 +83,60 @@ module Workflow
83
83
  rescue
84
84
  Log.exception $!
85
85
  end
86
+
86
87
  dep.task_name = task_name
87
- dep.overriden = dep.original_task_name.to_sym
88
+ dep.overriden = dep.original_task_name.to_sym if dep.original_task_name
88
89
 
89
90
  dep.extend step_module
90
91
 
91
92
  dep
92
93
  end
93
94
 
95
+ def assign_dep_inputs(_inputs, options, all_d, task_info)
96
+ IndiferentHash.setup(_inputs)
97
+
98
+ options.each{|i,v|
99
+ next if i == :compute or i == "compute"
100
+ case v
101
+ when :compute
102
+ compute = v
103
+ when Symbol
104
+ rec_dependency = all_d.flatten.select{|d| d.task_name.to_sym == v }.first
105
+
106
+ if rec_dependency.nil?
107
+ if _inputs.include?(v)
108
+ #_inputs[i] = _inputs.delete(v)
109
+ _inputs[i] = _inputs[v] unless _inputs.include? i #_inputs.delete(v)
110
+ else
111
+ _inputs[i] = v unless _inputs.include? i
112
+ end
113
+ else
114
+ input_options = task_info[:input_options][i] || {}
115
+
116
+ #ToDo why was this always true?
117
+ if input_options[:stream] or true
118
+ #rec_dependency.run(true).grace unless rec_dependency.done? or rec_dependency.running?
119
+ _inputs[i] = rec_dependency
120
+ else
121
+ rec_dependency.abort if rec_dependency.streaming? and not rec_dependency.running?
122
+ rec_dependency.clean if rec_dependency.error? or rec_dependency.aborted?
123
+ if rec_dependency.streaming? and rec_dependency.running?
124
+ _inputs[i] = rec_dependency.join.load
125
+ else
126
+ rec_dependency.run(true)
127
+ rec_dependency.join
128
+ _inputs[i] = rec_dependency.load
129
+ end
130
+ end
131
+ end
132
+ else
133
+ _inputs[i] = v
134
+ end
135
+ } if options
136
+
137
+ _inputs
138
+ end
139
+
94
140
  def real_dependencies(task, orig_jobname, inputs, dependencies)
95
141
  real_dependencies = []
96
142
  path_deps = {}
@@ -206,7 +206,7 @@ class Step
206
206
  if dup and step.streaming? and not step.result.nil?
207
207
  if dep_step[step.path] and dep_step[step.path].length > 1
208
208
  stream = step.result
209
- other_steps = dep_step[step.path].uniq
209
+ other_steps = dep_step[step.path].uniq.reject{|d| d.overriden }
210
210
  return unless other_steps.length > 1
211
211
  log_dependency_exec(step, "duplicating #{other_steps.length}")
212
212
  copies = Misc.tee_stream_thread_multiple(stream, other_steps.length)
@@ -523,4 +523,36 @@ class Step
523
523
  set_info :dependencies, dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]} if dependencies
524
524
  end
525
525
 
526
+ #connected = true means that dependency searching ends when a result is done
527
+ #but dependencies are absent, meanining that the file could have been dropped
528
+ #in
529
+ def rec_dependencies(connected = false, seen = [])
530
+
531
+ # A step result with no info_file means that it was manually
532
+ # placed. In that case, do not consider its dependencies
533
+ return [] if ! (defined? WorkflowRemoteClient && WorkflowRemoteClient::RemoteStep === self) && ! Open.exists?(self.info_file) && Open.exists?(self.path.to_s)
534
+
535
+ return [] if dependencies.nil? or dependencies.empty?
536
+
537
+ new_dependencies = []
538
+ if self.overriden?
539
+ archived_deps = []
540
+ else
541
+ archived_deps = self.info[:archived_info] ? self.info[:archived_info].keys : []
542
+ end
543
+
544
+ dependencies.each{|step|
545
+ #next if self.done? && Open.exists?(info_file) && info[:dependencies] && info[:dependencies].select{|task,name,path| path == step.path }.empty?
546
+ next if archived_deps.include? step.path
547
+ next if seen.include? step.path
548
+ next if self.done? && connected && ! updatable?
549
+
550
+ r = step.rec_dependencies(connected, new_dependencies.collect{|d| d.path})
551
+ new_dependencies.concat r
552
+ new_dependencies << step
553
+ }
554
+
555
+ new_dependencies.uniq
556
+ end
557
+
526
558
  end
@@ -179,6 +179,10 @@ class Step
179
179
  end
180
180
  end
181
181
 
182
+ def result_type=(type)
183
+ @result_type = type
184
+ end
185
+
182
186
  def result_description
183
187
  @result_description ||= if @task.nil?
184
188
  info[:result_description]
@@ -351,38 +355,6 @@ class Step
351
355
  end
352
356
  end
353
357
 
354
- #connected = true means that dependency searching ends when a result is done
355
- #but dependencies are absent, meanining that the file could have been dropped
356
- #in
357
- def rec_dependencies(connected = false, seen = [])
358
-
359
- # A step result with no info_file means that it was manually
360
- # placed. In that case, do not consider its dependencies
361
- return [] if ! (defined? WorkflowRemoteClient && WorkflowRemoteClient::RemoteStep === self) && ! Open.exists?(self.info_file) && Open.exists?(self.path.to_s)
362
-
363
- return [] if dependencies.nil? or dependencies.empty?
364
-
365
- new_dependencies = []
366
- if self.overriden?
367
- archived_deps = []
368
- else
369
- archived_deps = self.info[:archived_info] ? self.info[:archived_info].keys : []
370
- end
371
-
372
- dependencies.each{|step|
373
- #next if self.done? && Open.exists?(info_file) && info[:dependencies] && info[:dependencies].select{|task,name,path| path == step.path }.empty?
374
- next if archived_deps.include? step.path
375
- next if seen.include? step.path
376
- next if self.done? && connected && ! updatable?
377
-
378
- r = step.rec_dependencies(connected, new_dependencies.collect{|d| d.path})
379
- new_dependencies.concat r
380
- new_dependencies << step
381
- }
382
-
383
- new_dependencies.uniq
384
- end
385
-
386
358
  def writable?
387
359
  Open.writable?(self.path) && Open.writable?(self.info_file)
388
360
  end
@@ -3,13 +3,15 @@ require 'rbbt/workflow/examples'
3
3
 
4
4
  module Workflow
5
5
  module Data
6
- def data(directory)
6
+ class DataNotFound < RbbtException; end
7
+
8
+ def data_dir(directory)
7
9
  @@data_directory = directory
8
10
  end
9
11
 
10
12
  def get_datadir(clean_name)
11
13
  data_dir = File.join(@@data_directory, clean_name)
12
- raise "Data dir not found #{data_dir}" unless File.directory?(data_dir)
14
+ raise DataNotFound, "Data dir not found for #{clean_name} in #{@@data_directory}" unless File.directory?(data_dir)
13
15
  if Path === @@data_directory
14
16
  @@data_directory.annotate data_dir
15
17
  else
@@ -17,19 +19,147 @@ module Workflow
17
19
  end
18
20
  end
19
21
 
22
+ def get_file(clean_name, type = nil, extension = nil)
23
+ begin
24
+ extension = nil if String === extension && extension.empty?
25
+ file1 = File.join(@@data_directory, type.to_s, (extension.nil? ? clean_name.to_s : clean_name.to_s + ".#{extension}"))
26
+ file2 = File.join(@@data_directory, clean_name.to_s, (extension.nil? ? type.to_s : type.to_s + ".#{extension}"))
27
+ if Open.exists?(file1)
28
+ data_file = file1
29
+ elsif Open.exists?(file2)
30
+ data_file = file2
31
+ else
32
+ raise DataNotFound, "Data type #{type} not found for #{clean_name} in #{@@data_directory}"
33
+ end
34
+ end
35
+
36
+ if Path === @@data_directory
37
+ @@data_directory.annotate data_file
38
+ else
39
+ Path.setup(data_file)
40
+ end
41
+ end
42
+
20
43
  def data_task(name, workflow, oname, *rest, &block)
21
- dep_task(name, workflow, oname, *rest) do |jobname, options|
22
- data_dir = self.get_datadir(jobname)
23
- task_info = workflow.task_info(oname)
24
- dir_options = Workflow.load_inputs(data_dir.options, task_info[:inputs], task_info[:input_types])
25
- data_options = block.call data_dir, dir_options, task_info
26
- if data_options.include?(:inputs)
27
- data_options
44
+ dep_task(name, workflow, oname, *rest) do |jobname, options,dependencies|
45
+ begin
46
+ task_info = workflow.nil? ? nil : workflow.task_info(oname)
47
+ options[:extension] ||= task_info[:extension]
48
+ path = get_file jobname, name, options[:extension]
49
+ job = Step.new path
50
+ job.task_name = name
51
+ job.result_type = options[:result_type] || options[:type] || options[:extension]
52
+ job
53
+ rescue DataNotFound
54
+ end
55
+
56
+ next job if job
57
+
58
+ data_options = {}
59
+ data_options = data_options.merge(Workflow.load_inputs(File.join(@@data_directory,"options"), task_info[:inputs], task_info[:input_types]))
60
+
61
+ begin
62
+ data_options = data_options.merge(Workflow.load_inputs(get_file(jobname, :options), task_info[:inputs], task_info[:input_types]))
63
+ rescue DataNotFound
64
+ end
65
+
66
+ begin
67
+ data_options = data_options.merge(Workflow.load_inputs(get_datadir(jobname).options, task_info[:inputs], task_info[:input_types]))
68
+ rescue DataNotFound
69
+ end
70
+
71
+ begin
72
+ task_info = workflow.nil? ? nil : workflow.task_info(oname)
73
+ data_options = block.call get_datadir(jobname), data_options, task_info
74
+ rescue
75
+ Log.exception $!
76
+ end if block_given?
77
+
78
+ case data_options
79
+ when Step
80
+ next data_options
81
+ when Hash
82
+ if data_options.include?(:inputs)
83
+ data_options = data_options.merge(options)
84
+ workflow = data_options[:workflow] if data_options[:workflow]
85
+ oname = data_options[:task] if data_options[:task]
86
+ inputs = options.merge(data_options[:inputs])
87
+ else
88
+ inputs = options.merge(data_options)
89
+ end
90
+
91
+ {:workflow => workflow, :task => oname, :jobname => jobname, :inputs => inputs}
28
92
  else
29
- {:inputs => data_options.merge(options)}
93
+ raise "Cannot understand data_options: #{data_options}"
30
94
  end
95
+
31
96
  end
32
97
  end
33
- end
34
98
 
99
+ def data(name, options = {}, &block)
100
+ dep do |jobname, job_options, dependencies|
101
+ if block_given?
102
+ block.call jobname, job_options.merge(options), dependencies
103
+ else
104
+ begin
105
+ path = get_file jobname, name, options[:extension]
106
+ job = Step.new path
107
+ job.task_name = name
108
+ job.result_type = options[:result_type] || options[:type] || options[:extension]
109
+ job
110
+ rescue DataNotFound
111
+ {:task => name, :options => options, :jobname => jobname}
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
35
117
  end
118
+ #module Workflow
119
+ # module Data
120
+ # def data(directory)
121
+ # @@data_directory = directory
122
+ # end
123
+ #
124
+ # def get_datadir(clean_name)
125
+ # data_dir = File.join(@@data_directory, clean_name)
126
+ # raise "Data dir not found #{data_dir}" unless File.directory?(data_dir)
127
+ # if Path === @@data_directory
128
+ # @@data_directory.annotate data_dir
129
+ # else
130
+ # Path.setup(data_dir)
131
+ # end
132
+ # end
133
+ #
134
+ # def data_task(name, workflow, oname, *rest, &block)
135
+ # dep_task(name, workflow, oname, *rest) do |jobname, options|
136
+ # data_dir = self.get_datadir(jobname)
137
+ # task_info = workflow.task_info(oname)
138
+ #
139
+ # dir_options = Workflow.load_inputs(data_dir.options, task_info[:inputs], task_info[:input_types])
140
+ # data_options = block.call data_dir, dir_options, task_info
141
+ #
142
+ # case data_options
143
+ # when Step
144
+ # job = data_options
145
+ # when Hash
146
+ # if data_options.include?(:inputs)
147
+ # data_options = data_options.merge(options)
148
+ # workflow = data_options[:workflow] if data_options[:workflow]
149
+ # oname = data_options[:task] if data_options[:task]
150
+ # inputs = options.merge(data_options[:inputs])
151
+ # else
152
+ # inputs = options.merge(data_options)
153
+ # end
154
+ #
155
+ # job = workflow.job(oname, jobname, inputs)
156
+ # else
157
+ # raise "Cannot understand data_options: #{data_options}"
158
+ # end
159
+ #
160
+ # job
161
+ # end
162
+ # end
163
+ # end
164
+ #
165
+ #end
@@ -1,6 +1,16 @@
1
1
  require File.join(File.expand_path(File.dirname(__FILE__)), '../../..', 'test_helper.rb')
2
2
  require 'rbbt/workflow/util/data'
3
3
 
4
+ module TestDataWF2
5
+ extend Workflow
6
+ extend Workflow::Data
7
+
8
+ input :salutation, :string
9
+ task :salute_antonio => :string do |name,salutation|
10
+ "Hi Antonio: #{salutation}"
11
+ end
12
+ end
13
+
4
14
  module TestDataWF
5
15
  extend Workflow
6
16
  extend Workflow::Data
@@ -23,6 +33,11 @@ module TestDataWF
23
33
  data_task :salute_data2, TestDataWF, :salute, :salutation => :placeholder do |directory,options|
24
34
  {:task => :salute_luis, :inputs => options.merge({:salutation => directory.salutation.read})}
25
35
  end
36
+
37
+ data_task :salute_data3, TestDataWF, :salute, :salutation => :placeholder do |directory,options|
38
+ {:task => :salute_antonio, :workflow => TestDataWF2, :inputs => options.merge({:salutation => directory.salutation.read})}
39
+ end
40
+
26
41
  end
27
42
 
28
43
  class TestWorkflowData < Test::Unit::TestCase
@@ -33,15 +48,19 @@ class TestWorkflowData < Test::Unit::TestCase
33
48
  Open.write(tmpdir.TestDir.options.name, "Miguel")
34
49
  Open.write(tmpdir.TestDir.salutation, "My salutations")
35
50
 
36
- TestDataWF.data tmpdir
51
+ TestDataWF.data_dir tmpdir
37
52
 
38
53
  job = TestDataWF.job(:salute_data, "TestDir")
39
54
  job.recursive_clean.run
40
55
  assert job.run.include? "Miguel"
41
56
 
42
57
  job = TestDataWF.job(:salute_data2, "TestDir")
43
- job.recursive_clean.run
58
+ puts job.recursive_clean.run
44
59
  assert job.run.include? "Luis"
60
+
61
+ job = TestDataWF.job(:salute_data3, "TestDir")
62
+ job.recursive_clean.run
63
+ assert job.run.include? "Antonio"
45
64
  end
46
65
  end
47
66
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbbt-util
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.32.18
4
+ version: 5.32.23
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-14 00:00:00.000000000 Z
11
+ date: 2021-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake