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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aa5b1545b1a92199d163bf398ca973c6aa3d78ab37cc724b988e007c87824b3b
4
- data.tar.gz: 6cd3ce80ea589fb97a211ebe1d2973dd7c0d3f93b1ccefe10b9ecefbc77ff515
3
+ metadata.gz: 3a9ed1ed74562cdb81e14bb2b2213398646f76e532bdee48e67f9ff2f5330aad
4
+ data.tar.gz: e54ecf83a0b4323ffe98f8968f4a65acc2aae2ee5437330f44f14dc17c450ec5
5
5
  SHA512:
6
- metadata.gz: d8246d2a2686cc38086800fb6c30949bba93c8e78b7feac220b710a4e80f66858f979c5ea41de0beb67aeefd29de045e2315c3b50128f448bfef521ce3d52e15
7
- data.tar.gz: 26559322cae3bfb736565e8da0c7e63c3b006c793ab5cda8ec37a04fabfa460001bae6d7da8164ccd310730b81553d1d3b5a1d14cee9e6929793329ce508ec59
6
+ metadata.gz: 4d2eb887a184e24d78e8c565cefc25f09246d14e0f22d9a9037447806489cb4148fb2d9d3aad4cfe9bca1f256c0ec43afcc343047f20f974e6facea3214f40c0
7
+ data.tar.gz: 7f593e22911a501e353b6eb49830291a29b038474fd7bfc182e402f255219fc1eaf07311ad334118b43c275abc9ab2a5198d68ccbcdce7f3b4636c38dc698afd
@@ -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
- deps = seen[dep.path] ||= self.orchestrate_job(dep, options, skip_dep, seen)
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
- run_job(job, job_options)
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
@@ -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
@@ -349,7 +349,7 @@ module Persist
349
349
 
350
350
  Open.notify_write(path)
351
351
 
352
- return path if persist_options[:no_load]
352
+ return path if persist_options[:no_load] || type == :path
353
353
 
354
354
  res
355
355
  end
@@ -218,7 +218,14 @@ module Path
218
218
 
219
219
  else
220
220
  where = where.to_sym
221
- raise "Did not recognize the 'where' tag: #{where}. Options: #{paths.keys}" unless paths.include? where
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
- inputs = assign_dep_inputs({}, options.merge(d[:inputs] || {}), real_dependencies, task_info)
386
- d[:workflow]._job(d[:task], d[:jobname], inputs)
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
- inputs = assign_dep_inputs({}, dep[:inputs], real_dependencies, task_info)
404
- dep = dep[:workflow]._job(dep[:task], dep[:jobname], inputs)
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
@@ -315,6 +315,11 @@ class RemoteStep < Step
315
315
  end
316
316
  end
317
317
 
318
+ def workflow_short_path
319
+ init_job unless @url
320
+ [@base_url, @task, @name] * "/"
321
+ end
322
+
318
323
  def short_path
319
324
  init_job unless @url
320
325
  [@task, @name] * "/"
@@ -465,7 +465,10 @@ class Step
465
465
  self
466
466
  end
467
467
 
468
- def rec_dependencies(need_run = false, seen = [])
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? && need_run && ! updatable?
486
+ next if self.done? && connected && ! updatable?
484
487
 
485
- r = step.rec_dependencies(need_run, new_dependencies.collect{|d| d.path})
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
- (ENV["RBBT_UPDATE_ALL_JOBS"] == 'true' || ( ENV["RBBT_UPDATE"] == "true" && Open.exists?(info_file)) && status != :noinfo && ! (relocated? && done?)) || (ENV["RBBT_UPDATE"] && ! (done? && ! Open.exists?(info_file)))
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|
@@ -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 and input_options[i][:select_options] }.each{|i,t| selects << [i, input_options[i][:select_options]] }
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
- str << Log.color(:green, " " * (offset + 1) + Log.uncolor(prov_report_msg(dep.status, dep.info[:name], dep.path, dep.info)))
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.5
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-07 00:00:00.000000000 Z
11
+ date: 2021-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake