rbbt-util 5.30.5 → 5.30.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 +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
|