rbbt-util 5.30.5 → 5.30.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rbbt/hpc/orchestrate.rb +20 -3
- data/lib/rbbt/hpc/slurm.rb +6 -0
- data/lib/rbbt/persist.rb +1 -1
- data/lib/rbbt/resource/path.rb +8 -2
- data/lib/rbbt/workflow/accessor.rb +4 -4
- data/lib/rbbt/workflow/remote_workflow/remote_step.rb +5 -0
- data/lib/rbbt/workflow/step.rb +6 -3
- data/lib/rbbt/workflow/step/accessor.rb +7 -1
- data/lib/rbbt/workflow/step/run.rb +11 -6
- data/lib/rbbt/workflow/usage.rb +1 -1
- data/lib/rbbt/workflow/util/provenance.rb +8 -1
- data/share/rbbt_commands/slurm/list +8 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a9ed1ed74562cdb81e14bb2b2213398646f76e532bdee48e67f9ff2f5330aad
|
4
|
+
data.tar.gz: e54ecf83a0b4323ffe98f8968f4a65acc2aae2ee5437330f44f14dc17c450ec5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d2eb887a184e24d78e8c565cefc25f09246d14e0f22d9a9037447806489cb4148fb2d9d3aad4cfe9bca1f256c0ec43afcc343047f20f974e6facea3214f40c0
|
7
|
+
data.tar.gz: 7f593e22911a501e353b6eb49830291a29b038474fd7bfc182e402f255219fc1eaf07311ad334118b43c275abc9ab2a5198d68ccbcdce7f3b4636c38dc698afd
|
data/lib/rbbt/hpc/orchestrate.rb
CHANGED
@@ -59,7 +59,7 @@ module HPC
|
|
59
59
|
deps
|
60
60
|
end
|
61
61
|
|
62
|
-
def self.orchestrate_job(job, options, skip = false, seen = {})
|
62
|
+
def self.orchestrate_job(job, options, skip = false, seen = {}, chains = {})
|
63
63
|
return if job.done?
|
64
64
|
return unless job.path.split("/")[-4] == "jobs"
|
65
65
|
seen[:orchestration_target_job] ||= job
|
@@ -79,12 +79,15 @@ module HPC
|
|
79
79
|
|
80
80
|
deps = get_job_dependencies(job, job_rules)
|
81
81
|
|
82
|
+
chains[job.path] ||= []
|
82
83
|
dep_ids = deps.collect do |dep|
|
83
84
|
skip_dep = job_rules["chain_tasks"] &&
|
84
85
|
job_rules["chain_tasks"][job.workflow.to_s] && job_rules["chain_tasks"][job.workflow.to_s].include?(job.task_name.to_s) &&
|
85
86
|
job_rules["chain_tasks"][dep.workflow.to_s] && job_rules["chain_tasks"][dep.workflow.to_s].include?(dep.task_name.to_s)
|
86
87
|
|
87
|
-
|
88
|
+
chains[job.path] << dep if skip_dep
|
89
|
+
|
90
|
+
deps = seen[dep.path] ||= self.orchestrate_job(dep, options, skip_dep, seen, chains)
|
88
91
|
if job.canfail_paths.include? dep.path
|
89
92
|
[deps].flatten.compact.collect{|id| ['canfail', id] * ":"}
|
90
93
|
else
|
@@ -108,7 +111,21 @@ module HPC
|
|
108
111
|
job_options[:config_keys] = job_options[:config_keys] ? config_keys + "," + job_options[:config_keys] : config_keys
|
109
112
|
end
|
110
113
|
|
111
|
-
|
114
|
+
manifest = []
|
115
|
+
stack = [job]
|
116
|
+
while dep = stack.pop
|
117
|
+
manifest << dep
|
118
|
+
stack += chains[dep.path] if chains[dep.path]
|
119
|
+
end
|
120
|
+
|
121
|
+
job_options[:manifest] = manifest.uniq.collect{|dep| dep.workflow_short_path}
|
122
|
+
|
123
|
+
if options[:dry_run]
|
124
|
+
puts Log.color(:yellow, "Manifest: ") + Log.color(:blue, job_options[:manifest] * ", ") + " - tasks: #{job_options[:task_cpus] || 1} - time: #{job_options[:time]} - config: #{job_options[:config_keys]}"
|
125
|
+
[]
|
126
|
+
else
|
127
|
+
run_job(job, job_options)
|
128
|
+
end
|
112
129
|
end
|
113
130
|
end
|
114
131
|
end
|
data/lib/rbbt/hpc/slurm.rb
CHANGED
@@ -21,6 +21,8 @@ module HPC
|
|
21
21
|
exclusive = options.delete :exclusive
|
22
22
|
highmem = options.delete :highmem
|
23
23
|
|
24
|
+
manifest = options.delete :manifest
|
25
|
+
|
24
26
|
queue = options.delete(:queue) || Rbbt::Config.get('queue', :slurm_queue, :slurm, :SLURM, :default => 'bsc_ls')
|
25
27
|
task_cpus = options.delete(:task_cpus) || 1
|
26
28
|
nodes = options.delete(:nodes) || 1
|
@@ -258,6 +260,10 @@ EOF
|
|
258
260
|
workflow write_info --recursive --force=false --check_pid "$step_path" slurm_job $SLURM_JOB_ID
|
259
261
|
EOF
|
260
262
|
|
263
|
+
header +=<<-EOF if manifest
|
264
|
+
#MANIFEST: #{manifest * ", "}
|
265
|
+
EOF
|
266
|
+
|
261
267
|
header +=<<-EOF
|
262
268
|
#CMD: #{rbbt_cmd}
|
263
269
|
EOF
|
data/lib/rbbt/persist.rb
CHANGED
data/lib/rbbt/resource/path.rb
CHANGED
@@ -218,7 +218,14 @@ module Path
|
|
218
218
|
|
219
219
|
else
|
220
220
|
where = where.to_sym
|
221
|
-
|
221
|
+
|
222
|
+
if paths.include? where
|
223
|
+
path = paths[where]
|
224
|
+
elsif where.to_s.include?("/")
|
225
|
+
path = where.to_s
|
226
|
+
else
|
227
|
+
raise "Did not recognize the 'where' tag: #{where}. Options: #{paths.keys}" unless paths.include? where
|
228
|
+
end
|
222
229
|
|
223
230
|
if where == :lib
|
224
231
|
libdir = @libdir || Path.caller_lib_dir(caller_lib) || "NOLIBDIR"
|
@@ -227,7 +234,6 @@ module Path
|
|
227
234
|
end
|
228
235
|
|
229
236
|
pwd = FileUtils.pwd
|
230
|
-
path = paths[where]
|
231
237
|
path = File.join(path, "{PATH}") unless path.include? "PATH}" or path.include? "{BASENAME}"
|
232
238
|
path = path.
|
233
239
|
sub('{PKGDIR}', pkgdir).
|
@@ -382,8 +382,8 @@ module Workflow
|
|
382
382
|
else
|
383
383
|
task_info = d[:workflow].task_info(d[:task])
|
384
384
|
|
385
|
-
|
386
|
-
d[:workflow]._job(d[:task], d[:jobname],
|
385
|
+
_inputs = assign_dep_inputs({}, options.merge(d[:inputs] || {}), real_dependencies, task_info)
|
386
|
+
d[:workflow]._job(d[:task], d[:jobname], _inputs)
|
387
387
|
end
|
388
388
|
end
|
389
389
|
ComputeDependency.setup(d, compute) if compute
|
@@ -400,8 +400,8 @@ module Workflow
|
|
400
400
|
setup_override_dependency(value, dep[:workflow], dep[:task])
|
401
401
|
else
|
402
402
|
task_info = (dep[:task] && dep[:workflow]) ? dep[:workflow].task_info(dep[:task]) : nil
|
403
|
-
|
404
|
-
dep = dep[:workflow]._job(dep[:task], dep[:jobname],
|
403
|
+
_inputs = assign_dep_inputs({}, dep[:inputs], real_dependencies, task_info)
|
404
|
+
dep = dep[:workflow]._job(dep[:task], dep[:jobname], _inputs)
|
405
405
|
end
|
406
406
|
end
|
407
407
|
end
|
data/lib/rbbt/workflow/step.rb
CHANGED
@@ -465,7 +465,10 @@ class Step
|
|
465
465
|
self
|
466
466
|
end
|
467
467
|
|
468
|
-
|
468
|
+
#connected = true means that dependency searching ends when a result is done
|
469
|
+
#but dependencies are absent, meanining that the file could have been dropped
|
470
|
+
#in
|
471
|
+
def rec_dependencies(connected = false, seen = [])
|
469
472
|
|
470
473
|
# A step result with no info_file means that it was manually
|
471
474
|
# placed. In that case, do not consider its dependencies
|
@@ -480,9 +483,9 @@ class Step
|
|
480
483
|
#next if self.done? && Open.exists?(info_file) && info[:dependencies] && info[:dependencies].select{|task,name,path| path == step.path }.empty?
|
481
484
|
next if archived_deps.include? step.path
|
482
485
|
next if seen.include? step.path
|
483
|
-
next if self.done? &&
|
486
|
+
next if self.done? && connected && ! updatable?
|
484
487
|
|
485
|
-
r = step.rec_dependencies(
|
488
|
+
r = step.rec_dependencies(connected, new_dependencies.collect{|d| d.path})
|
486
489
|
new_dependencies.concat r
|
487
490
|
new_dependencies << step
|
488
491
|
}
|
@@ -154,10 +154,16 @@ class Step
|
|
154
154
|
@name ||= path.sub(/.*\/#{Regexp.quote task_name.to_s}\/(.*)/, '\1')
|
155
155
|
end
|
156
156
|
|
157
|
+
|
157
158
|
def short_path
|
158
159
|
[task_name, name] * "/"
|
159
160
|
end
|
160
161
|
|
162
|
+
def workflow_short_path
|
163
|
+
return short_path unless workflow
|
164
|
+
workflow.to_s + "#" + short_path
|
165
|
+
end
|
166
|
+
|
161
167
|
def task_name
|
162
168
|
@task_name ||= task.name
|
163
169
|
end
|
@@ -456,7 +462,7 @@ class Step
|
|
456
462
|
end
|
457
463
|
|
458
464
|
def dirty_files
|
459
|
-
rec_dependencies = self.rec_dependencies
|
465
|
+
rec_dependencies = self.rec_dependencies(true)
|
460
466
|
return [] if rec_dependencies.empty?
|
461
467
|
canfail_paths = self.canfail_paths
|
462
468
|
|
@@ -112,23 +112,27 @@ class Step
|
|
112
112
|
end
|
113
113
|
|
114
114
|
def updatable?
|
115
|
-
|
115
|
+
return true if ENV["RBBT_UPDATE_ALL_JOBS"] == 'true'
|
116
|
+
return false unless ENV["RBBT_UPDATE"] == "true"
|
117
|
+
return false unless Open.exists?(info_file)
|
118
|
+
return true if status != :noinfo && ! (relocated? && done?)
|
119
|
+
false
|
116
120
|
end
|
117
121
|
|
118
122
|
def dependency_checks
|
119
123
|
return [] if ENV["RBBT_UPDATE"] != "true"
|
120
124
|
|
121
|
-
rec_dependencies.
|
125
|
+
rec_dependencies(true).
|
122
126
|
reject{|dependency| (defined?(WorkflowRemoteClient) && WorkflowRemoteClient::RemoteStep === dependency) || Open.remote?(dependency.path) }.
|
123
127
|
reject{|dependency| dependency.error? }.
|
124
128
|
#select{|dependency| Open.exists?(dependency.path) || ((Open.exists?(dependency.info_file) && (dependency.status == :cleaned) || dependency.status == :waiting)) }.
|
125
|
-
select{|dependency| dependency.updatable? }.
|
129
|
+
#select{|dependency| dependency.updatable? }.
|
126
130
|
collect{|dependency| Workflow.relocate_dependency(self, dependency)}
|
127
131
|
end
|
128
132
|
|
129
133
|
def input_checks
|
130
|
-
(inputs.select{|i| Step === i } + inputs.select{|i| Path === i && Step === i.resource}.collect{|i| i.resource})
|
131
|
-
select{|dependency| dependency.updatable? }
|
134
|
+
(inputs.select{|i| Step === i } + inputs.select{|i| Path === i && Step === i.resource}.collect{|i| i.resource})
|
135
|
+
#select{|dependency| dependency.updatable? }
|
132
136
|
end
|
133
137
|
|
134
138
|
def checks
|
@@ -153,7 +157,8 @@ class Step
|
|
153
157
|
canfail_paths = self.canfail_paths
|
154
158
|
this_mtime = Open.mtime(self.path) if Open.exists?(self.path)
|
155
159
|
|
156
|
-
outdated_time = checks.select{|dep| dep.updatable? && dep.done? && Persist.newer?(path, dep.path) }
|
160
|
+
#outdated_time = checks.select{|dep| dep.updatable? && dep.done? && Persist.newer?(path, dep.path) }
|
161
|
+
outdated_time = checks.select{|dep| dep.done? && Persist.newer?(path, dep.path) }
|
157
162
|
outdated_dep = checks.reject{|dep| dep.done? || (dep.error? && ! dep.recoverable_error? && canfail_paths.include?(dep.path)) }
|
158
163
|
|
159
164
|
#checks.each do |dep|
|
data/lib/rbbt/workflow/usage.rb
CHANGED
@@ -21,7 +21,7 @@ module Task
|
|
21
21
|
|
22
22
|
selects = []
|
23
23
|
if inputs.any?
|
24
|
-
inputs.zip(input_types.values_at(*inputs)).select{|i,t| t.to_sym == :select
|
24
|
+
inputs.zip(input_types.values_at(*inputs)).select{|i,t| t.to_sym == :select && input_options[i] && input_options[i][:select_options] }.each{|i,t| selects << [i, input_options[i][:select_options]] }
|
25
25
|
puts SOPT.input_doc(inputs, input_types, input_descriptions, input_defaults, true)
|
26
26
|
puts
|
27
27
|
end
|
@@ -91,7 +91,14 @@ class Step
|
|
91
91
|
if expand_repeats
|
92
92
|
str << Log.color(:green, Log.uncolor(prov_report(dep, offset+1, task)))
|
93
93
|
else
|
94
|
-
|
94
|
+
info = dep.info || {}
|
95
|
+
status = info[:status] || :missing
|
96
|
+
status = "remote" if Open.remote?(path) || Open.ssh?(path)
|
97
|
+
name = info[:name] || File.basename(path)
|
98
|
+
status = :unsync if status == :done and not Open.exist?(path)
|
99
|
+
status = :notfound if status == :noinfo and not Open.exist?(path)
|
100
|
+
|
101
|
+
str << Log.color(status == :notfound ? :blue : :green, " " * (offset + 1) + Log.uncolor(prov_report_msg(status, name, path, info)))
|
95
102
|
end
|
96
103
|
end
|
97
104
|
end if step.dependencies
|
@@ -70,6 +70,13 @@ workdir.glob("**/command.slurm").sort_by{|f| File.mtime(f)}.each do |fcmd|
|
|
70
70
|
cmd = nil
|
71
71
|
end
|
72
72
|
|
73
|
+
if m = Open.read(fcmd).match(/#MANIFEST: (.*)/)
|
74
|
+
manifest = m[1]
|
75
|
+
else
|
76
|
+
manifest = nil
|
77
|
+
end
|
78
|
+
|
79
|
+
|
73
80
|
if m = Open.read(fcmd).match(/# Run command\n(.*?)\n/im)
|
74
81
|
exe = m[1].sub('step_path=$(','')
|
75
82
|
else
|
@@ -145,6 +152,7 @@ workdir.glob("**/command.slurm").sort_by{|f| File.mtime(f)}.each do |fcmd|
|
|
145
152
|
puts Log.color :blue, dir
|
146
153
|
puts Log.color(:magenta, "Creation: ") << File.mtime(File.join(dir, 'command.slurm')).to_s
|
147
154
|
puts Log.color(:magenta, "Started: ") << File.ctime(File.join(dir, 'std.err')).to_s if File.exist?(File.join(dir, 'std.err'))
|
155
|
+
puts Log.color(:magenta, "Manifest: ") << Log.color(:yellow, manifest)
|
148
156
|
puts Log.color(:magenta, "Done: ") << File.mtime(File.join(dir, 'exit.status')).to_s if File.exist?(File.join(dir, 'exit.status'))
|
149
157
|
puts Log.color(:magenta, "Exec: ") << (exe || "Missing")
|
150
158
|
puts Log.color(:magenta, "CMD: ") << (Log.color(:yellow, cmd) || "Missing")
|
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.30.
|
4
|
+
version: 5.30.6
|
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-02-
|
11
|
+
date: 2021-02-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|