rbbt-util 5.44.1 → 6.0.4
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/LICENSE +1 -1
- data/bin/rbbt +67 -90
- data/bin/rbbt_exec.rb +2 -2
- data/etc/app.d/base.rb +2 -2
- data/etc/app.d/semaphores.rb +3 -3
- data/lib/rbbt/annotations/annotated_array.rb +207 -207
- data/lib/rbbt/annotations/refactor.rb +27 -0
- data/lib/rbbt/annotations/util.rb +282 -282
- data/lib/rbbt/annotations.rb +343 -320
- data/lib/rbbt/association/database.rb +200 -225
- data/lib/rbbt/association/index.rb +294 -291
- data/lib/rbbt/association/item.rb +227 -227
- data/lib/rbbt/association/open.rb +35 -34
- data/lib/rbbt/association/util.rb +0 -169
- data/lib/rbbt/association.rb +2 -4
- data/lib/rbbt/entity/identifiers.rb +119 -118
- data/lib/rbbt/entity/refactor.rb +12 -0
- data/lib/rbbt/entity.rb +319 -315
- data/lib/rbbt/hpc/batch.rb +72 -53
- data/lib/rbbt/hpc/lsf.rb +2 -2
- data/lib/rbbt/hpc/orchestrate/batches.rb +2 -2
- data/lib/rbbt/hpc/orchestrate/chains.rb +25 -5
- data/lib/rbbt/hpc/orchestrate/rules.rb +2 -2
- data/lib/rbbt/hpc/orchestrate.rb +19 -13
- data/lib/rbbt/hpc/slurm.rb +18 -18
- data/lib/rbbt/knowledge_base/entity.rb +13 -5
- data/lib/rbbt/knowledge_base/query.rb +2 -2
- data/lib/rbbt/knowledge_base/registry.rb +32 -31
- data/lib/rbbt/knowledge_base/traverse.rb +1 -1
- data/lib/rbbt/knowledge_base.rb +1 -1
- data/lib/rbbt/monitor.rb +36 -25
- data/lib/rbbt/persist/refactor.rb +166 -0
- data/lib/rbbt/persist/tsv/tokyocabinet.rb +105 -105
- data/lib/rbbt/persist/tsv.rb +187 -185
- data/lib/rbbt/persist.rb +556 -551
- data/lib/rbbt/refactor.rb +20 -0
- data/lib/rbbt/resource/path/refactor.rb +178 -0
- data/lib/rbbt/resource/path.rb +317 -497
- data/lib/rbbt/resource/util.rb +0 -48
- data/lib/rbbt/resource.rb +3 -390
- data/lib/rbbt/tsv/accessor.rb +2 -838
- data/lib/rbbt/tsv/attach.rb +303 -299
- data/lib/rbbt/tsv/change_id.rb +244 -245
- data/lib/rbbt/tsv/csv.rb +87 -85
- data/lib/rbbt/tsv/dumper.rb +2 -100
- data/lib/rbbt/tsv/excel.rb +26 -24
- data/lib/rbbt/tsv/field_index.rb +4 -1
- data/lib/rbbt/tsv/filter.rb +3 -2
- data/lib/rbbt/tsv/index.rb +2 -284
- data/lib/rbbt/tsv/manipulate.rb +750 -747
- data/lib/rbbt/tsv/marshal.rb +3 -3
- data/lib/rbbt/tsv/matrix.rb +2 -2
- data/lib/rbbt/tsv/parallel/through.rb +2 -1
- data/lib/rbbt/tsv/parallel/traverse.rb +783 -781
- data/lib/rbbt/tsv/parser.rb +678 -678
- data/lib/rbbt/tsv/refactor.rb +195 -0
- data/lib/rbbt/tsv/stream.rb +253 -251
- data/lib/rbbt/tsv/util.rb +420 -420
- data/lib/rbbt/tsv.rb +210 -208
- data/lib/rbbt/util/R/eval.rb +4 -4
- data/lib/rbbt/util/R/plot.rb +62 -166
- data/lib/rbbt/util/R.rb +21 -18
- data/lib/rbbt/util/cmd.rb +2 -318
- data/lib/rbbt/util/color.rb +269 -269
- data/lib/rbbt/util/colorize.rb +89 -89
- data/lib/rbbt/util/concurrency/processes/refactor.rb +22 -0
- data/lib/rbbt/util/concurrency/processes/worker.rb +2 -2
- data/lib/rbbt/util/concurrency/processes.rb +389 -386
- data/lib/rbbt/util/config.rb +169 -167
- data/lib/rbbt/util/filecache.rb +1 -1
- data/lib/rbbt/util/iruby.rb +20 -0
- data/lib/rbbt/util/log/progress/report.rb +241 -241
- data/lib/rbbt/util/log/progress/util.rb +99 -99
- data/lib/rbbt/util/log/progress.rb +102 -102
- data/lib/rbbt/util/log/refactor.rb +49 -0
- data/lib/rbbt/util/log.rb +486 -532
- data/lib/rbbt/util/migrate.rb +2 -2
- data/lib/rbbt/util/misc/concurrent_stream.rb +248 -246
- data/lib/rbbt/util/misc/development.rb +12 -11
- data/lib/rbbt/util/misc/exceptions.rb +117 -112
- data/lib/rbbt/util/misc/format.rb +2 -230
- data/lib/rbbt/util/misc/indiferent_hash.rb +2 -107
- data/lib/rbbt/util/misc/inspect.rb +2 -476
- data/lib/rbbt/util/misc/lock.rb +109 -106
- data/lib/rbbt/util/misc/omics.rb +9 -1
- data/lib/rbbt/util/misc/pipes.rb +765 -793
- data/lib/rbbt/util/misc/refactor.rb +20 -0
- data/lib/rbbt/util/misc/ssw.rb +27 -17
- data/lib/rbbt/util/misc/system.rb +92 -105
- data/lib/rbbt/util/misc.rb +39 -20
- data/lib/rbbt/util/named_array/refactor.rb +4 -0
- data/lib/rbbt/util/named_array.rb +3 -220
- data/lib/rbbt/util/open/refactor.rb +7 -0
- data/lib/rbbt/util/open.rb +3 -857
- data/lib/rbbt/util/procpath.rb +6 -6
- data/lib/rbbt/util/python/paths.rb +27 -0
- data/lib/rbbt/util/python/run.rb +115 -0
- data/lib/rbbt/util/python/script.rb +110 -0
- data/lib/rbbt/util/python/util.rb +3 -3
- data/lib/rbbt/util/python.rb +22 -81
- data/lib/rbbt/util/semaphore.rb +152 -148
- data/lib/rbbt/util/simpleopt.rb +9 -8
- data/lib/rbbt/util/ssh/refactor.rb +19 -0
- data/lib/rbbt/util/ssh.rb +122 -118
- data/lib/rbbt/util/tar.rb +117 -115
- data/lib/rbbt/util/tmpfile.rb +69 -67
- data/lib/rbbt/util/version.rb +2 -0
- data/lib/rbbt/workflow/refactor/entity.rb +11 -0
- data/lib/rbbt/workflow/refactor/export.rb +66 -0
- data/lib/rbbt/workflow/refactor/inputs.rb +24 -0
- data/lib/rbbt/workflow/refactor/recursive.rb +64 -0
- data/lib/rbbt/workflow/refactor/task_info.rb +66 -0
- data/lib/rbbt/workflow/refactor.rb +150 -0
- data/lib/rbbt/workflow/remote_workflow/driver/rest.rb +1 -2
- data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +55 -32
- data/lib/rbbt/workflow/remote_workflow/remote_step/rest.rb +3 -1
- data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +14 -5
- data/lib/rbbt/workflow/remote_workflow/remote_step.rb +19 -7
- data/lib/rbbt/workflow/remote_workflow.rb +6 -1
- data/lib/rbbt/workflow/step/run.rb +766 -766
- data/lib/rbbt/workflow/step/save_load_inputs.rb +254 -254
- data/lib/rbbt/workflow/step.rb +2 -362
- data/lib/rbbt/workflow/task.rb +118 -118
- data/lib/rbbt/workflow/usage.rb +289 -287
- data/lib/rbbt/workflow/util/archive.rb +6 -5
- data/lib/rbbt/workflow/util/data.rb +1 -1
- data/lib/rbbt/workflow/util/orchestrator.rb +249 -246
- data/lib/rbbt/workflow/util/trace.rb +79 -44
- data/lib/rbbt/workflow.rb +4 -882
- data/lib/rbbt-util.rb +21 -13
- data/lib/rbbt.rb +16 -3
- data/python/rbbt/__init__.py +96 -4
- data/python/rbbt/workflow/remote.py +104 -0
- data/python/rbbt/workflow.py +64 -0
- data/python/test.py +10 -0
- data/share/Rlib/plot.R +37 -37
- data/share/Rlib/svg.R +22 -5
- data/share/install/software/lib/install_helpers +1 -1
- data/share/rbbt_commands/hpc/list +2 -3
- data/share/rbbt_commands/hpc/orchestrate +4 -4
- data/share/rbbt_commands/hpc/tail +2 -0
- data/share/rbbt_commands/hpc/task +10 -7
- data/share/rbbt_commands/lsf/list +2 -3
- data/share/rbbt_commands/lsf/orchestrate +4 -4
- data/share/rbbt_commands/lsf/tail +2 -0
- data/share/rbbt_commands/lsf/task +10 -7
- data/share/rbbt_commands/migrate +1 -1
- data/share/rbbt_commands/pbs/list +2 -3
- data/share/rbbt_commands/pbs/orchestrate +4 -4
- data/share/rbbt_commands/pbs/tail +2 -0
- data/share/rbbt_commands/pbs/task +10 -7
- data/share/rbbt_commands/resource/produce +8 -1
- data/share/rbbt_commands/slurm/list +2 -3
- data/share/rbbt_commands/slurm/orchestrate +4 -4
- data/share/rbbt_commands/slurm/tail +2 -0
- data/share/rbbt_commands/slurm/task +10 -7
- data/share/rbbt_commands/system/clean +5 -5
- data/share/rbbt_commands/system/status +5 -5
- data/share/rbbt_commands/tsv/get +2 -3
- data/share/rbbt_commands/tsv/info +10 -13
- data/share/rbbt_commands/tsv/keys +18 -14
- data/share/rbbt_commands/tsv/slice +2 -2
- data/share/rbbt_commands/tsv/transpose +6 -2
- data/share/rbbt_commands/workflow/info +20 -24
- data/share/rbbt_commands/workflow/list +1 -1
- data/share/rbbt_commands/workflow/prov +20 -13
- data/share/rbbt_commands/workflow/retry +43 -0
- data/share/rbbt_commands/workflow/server +12 -2
- data/share/rbbt_commands/workflow/task +80 -73
- data/share/rbbt_commands/workflow/write_info +26 -9
- data/share/software/opt/ssw/ssw.c +861 -0
- data/share/software/opt/ssw/ssw.h +130 -0
- data/share/workflow_config.ru +3 -3
- metadata +45 -6
data/lib/rbbt/hpc/batch.rb
CHANGED
@@ -24,7 +24,7 @@ module HPC
|
|
24
24
|
when 'pbs'
|
25
25
|
HPC::PBS
|
26
26
|
else
|
27
|
-
case
|
27
|
+
case Scout::Config.get(:batch_system, :batch, :batch_system, :hpc, :HPC, :BATCH).to_s.downcase
|
28
28
|
when 'slurm'
|
29
29
|
HPC::SLURM
|
30
30
|
when 'lsf'
|
@@ -47,8 +47,9 @@ module HPC
|
|
47
47
|
|
48
48
|
module TemplateGeneration
|
49
49
|
def exec_cmd(job, options = {})
|
50
|
-
|
51
|
-
|
50
|
+
options = IndiferentHash.add_defaults options, :launcher => :srun if HPC.batch_system == SLURM
|
51
|
+
|
52
|
+
launcher, env_cmd, development = IndiferentHash.process_options options, :launcher, :env_cmd, :development
|
52
53
|
|
53
54
|
if contain = options[:contain]
|
54
55
|
contain = File.expand_path(contain)
|
@@ -87,10 +88,16 @@ module HPC
|
|
87
88
|
singularity_cmd << " #{singularity_img} "
|
88
89
|
end
|
89
90
|
|
91
|
+
base_cmd = if launcher
|
92
|
+
%(#{launcher} rbbt)
|
93
|
+
else
|
94
|
+
%(rbbt)
|
95
|
+
end
|
96
|
+
|
90
97
|
if env_cmd
|
91
|
-
exec_cmd = %(env #{env_cmd}
|
98
|
+
exec_cmd = %(env #{env_cmd} #{ base_cmd })
|
92
99
|
else
|
93
|
-
exec_cmd =
|
100
|
+
exec_cmd = base_cmd
|
94
101
|
end
|
95
102
|
|
96
103
|
exec_cmd << "--dev '#{development}'" if development
|
@@ -103,36 +110,29 @@ module HPC
|
|
103
110
|
def rbbt_job_exec_cmd(job, options)
|
104
111
|
|
105
112
|
jobname = job.clean_name
|
106
|
-
workflow = job.
|
107
|
-
task = job.
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
task =
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
# collect do |dep|
|
126
|
-
# name = [dep.workflow.to_s, dep.task_name] * "#"
|
127
|
-
# [name, dep.path] * "="
|
128
|
-
# end.uniq * ","
|
129
|
-
|
130
|
-
# options[:override_deps] = override_deps unless override_deps.empty?
|
131
|
-
#end
|
113
|
+
workflow = job.workflow
|
114
|
+
task = job.task_name
|
115
|
+
|
116
|
+
IndiferentHash.add_defaults options, :jobname => jobname
|
117
|
+
|
118
|
+
task = job.task_name
|
119
|
+
|
120
|
+
if job.recursive_overriden_deps.any?
|
121
|
+
override_deps = job.recursive_overriden_deps.
|
122
|
+
select do |dep| Symbol === dep.overriden end.
|
123
|
+
collect do |dep|
|
124
|
+
o_workflow = dep.overriden_workflow || dep.workflow
|
125
|
+
o_workflow = o_workflow.name if o_workflow.respond_to?(:name)
|
126
|
+
o_task_name = dep.overriden_task || dep.task.name
|
127
|
+
name = [o_workflow, o_task_name] * "#"
|
128
|
+
[name, dep.path] * "="
|
129
|
+
end.uniq * ","
|
130
|
+
options[:override_deps] = override_deps unless override_deps.empty?
|
131
|
+
end
|
132
132
|
|
133
133
|
# Save inputs into inputs_dir
|
134
|
-
inputs_dir =
|
135
|
-
saved =
|
134
|
+
inputs_dir = IndiferentHash.process_options options, :inputs_dir
|
135
|
+
saved = job.save_inputs(inputs_dir)
|
136
136
|
options[:load_inputs] = inputs_dir if saved && saved.any?
|
137
137
|
|
138
138
|
saved.each do |input|
|
@@ -181,8 +181,10 @@ EOF
|
|
181
181
|
:sync,
|
182
182
|
:contain_and_sync,
|
183
183
|
:copy_image,
|
184
|
-
:
|
184
|
+
:launcher,
|
185
|
+
:development,
|
185
186
|
:env_cmd,
|
187
|
+
:env,
|
186
188
|
:manifest,
|
187
189
|
:user_group,
|
188
190
|
:wipe_container,
|
@@ -197,7 +199,7 @@ EOF
|
|
197
199
|
|
198
200
|
keys.each do |key|
|
199
201
|
next if options[key].nil?
|
200
|
-
batch_options[key] =
|
202
|
+
batch_options[key] = IndiferentHash.process_options options, key
|
201
203
|
end
|
202
204
|
|
203
205
|
batch_dir = batch_options[:batch_dir]
|
@@ -209,7 +211,10 @@ EOF
|
|
209
211
|
:queue,
|
210
212
|
:highmem,
|
211
213
|
:exclusive,
|
214
|
+
:launcher,
|
215
|
+
:development,
|
212
216
|
:env_cmd,
|
217
|
+
:env,
|
213
218
|
:user_group,
|
214
219
|
:singularity_img,
|
215
220
|
:singularity_mounts,
|
@@ -220,9 +225,9 @@ EOF
|
|
220
225
|
|
221
226
|
keys_from_config.each do |key|
|
222
227
|
next unless batch_options.include? key
|
223
|
-
default_value =
|
228
|
+
default_value = Scout::Config.get(key, "batch_#{key}", "batch")
|
224
229
|
next if default_value.nil?
|
225
|
-
|
230
|
+
IndiferentHash.add_defaults batch_options, default_value
|
226
231
|
end
|
227
232
|
|
228
233
|
user = batch_options[:user] ||= ENV['USER'] || `whoami`.strip
|
@@ -234,7 +239,7 @@ EOF
|
|
234
239
|
|
235
240
|
if batch_options[:contain_and_sync]
|
236
241
|
if batch_options[:contain].nil?
|
237
|
-
contain_base =
|
242
|
+
contain_base = Scout::Config.get(:contain_base_dir, :batch_contain, :batch, :default => "/scratch/tmp/rbbt-[USER]")
|
238
243
|
contain_base = contain_base.sub('[USER]', user)
|
239
244
|
random_file = TmpFile.random_name
|
240
245
|
batch_options[:contain] = File.join(contain_base, random_file)
|
@@ -248,14 +253,14 @@ EOF
|
|
248
253
|
options[:workdir_all] = batch_options[:contain]
|
249
254
|
end
|
250
255
|
|
251
|
-
|
256
|
+
IndiferentHash.add_defaults batch_options,
|
252
257
|
:batch_name => batch_name,
|
253
258
|
:inputs_dir => inputs_dir,
|
254
259
|
:nodes => 1,
|
255
260
|
:step_path => job.path,
|
256
261
|
:task_cpus => 1,
|
257
262
|
:time => '2min',
|
258
|
-
:
|
263
|
+
:env => {'JDK_JAVA_OPTIONS' => "-Xms1g -Xmx${MAX_MEMORY}m"},
|
259
264
|
:singularity_img => ENV["SINGULARITY_IMG"] || "~/rbbt.singularity.img",
|
260
265
|
:singularity_ruby_inline => ENV["SINGULARITY_RUBY_INLINE"] || "~/.singularity_ruby_inline",
|
261
266
|
:singularity_opt_dir => ENV["SINGULARITY_OPT_DIR"] || "~/singularity_opt",
|
@@ -264,13 +269,13 @@ EOF
|
|
264
269
|
exec_cmd = exec_cmd(job, batch_options)
|
265
270
|
rbbt_cmd = rbbt_job_exec_cmd(job, options)
|
266
271
|
|
267
|
-
|
272
|
+
IndiferentHash.add_defaults batch_options,
|
268
273
|
:exec_cmd => exec_cmd,
|
269
274
|
:rbbt_cmd => rbbt_cmd
|
270
275
|
|
271
276
|
batch_dir = batch_options[:batch_dir]
|
272
277
|
|
273
|
-
|
278
|
+
IndiferentHash.add_defaults batch_options,
|
274
279
|
:fout => File.join(batch_dir, 'std.out'),
|
275
280
|
:ferr => File.join(batch_dir, 'std.err'),
|
276
281
|
:fjob => File.join(batch_dir, 'job.id'),
|
@@ -380,6 +385,13 @@ function batch_sync_contain_dir(){
|
|
380
385
|
EOF
|
381
386
|
end
|
382
387
|
|
388
|
+
if options[:env]
|
389
|
+
prepare_environment +=<<-EOF
|
390
|
+
# Set ENV variables
|
391
|
+
#{options[:env].collect{|n,v| "export #{n}=\"#{v}\"" } * "\n"}
|
392
|
+
EOF
|
393
|
+
end
|
394
|
+
|
383
395
|
if options[:singularity]
|
384
396
|
|
385
397
|
group, user, user_group, scratch_group_dir, projects_group_dir = options.values_at :group, :user, :user_group, :scratch_group_dir, :projects_group_dir
|
@@ -421,7 +433,7 @@ echo "user_scratch: #{scratch_group_dir}/#{user}/{PKGDIR}/{TOPLEVEL}/{SUBPATH}"
|
|
421
433
|
end
|
422
434
|
end
|
423
435
|
|
424
|
-
batch_system_variables
|
436
|
+
[batch_system_variables, load_modules(modules), load_conda(conda), functions, prepare_environment].reject{|s| s.empty? } * "\n"
|
425
437
|
end
|
426
438
|
|
427
439
|
def execute(options)
|
@@ -433,9 +445,11 @@ step_path=$(
|
|
433
445
|
)
|
434
446
|
exit_status=$?
|
435
447
|
|
436
|
-
[
|
437
|
-
[[ -z $
|
438
|
-
#{exec_cmd} workflow write_info --recursive --force=false --check_pid "$step_path"
|
448
|
+
if [ $exit_status -eq 0 ]; then
|
449
|
+
[[ -z $BATCH_JOB_ID ]] || #{exec_cmd} workflow write_info --recursive --force=false --check_pid "$step_path" batch_job $BATCH_JOB_ID
|
450
|
+
[[ -z $BATCH_SYSTEM ]] || #{exec_cmd} workflow write_info --recursive --force=false --check_pid "$step_path" batch_system $BATCH_SYSTEM
|
451
|
+
#{exec_cmd} workflow write_info --recursive --force=false --check_pid "$step_path" batch_cpus #{task_cpus}
|
452
|
+
fi
|
439
453
|
EOF
|
440
454
|
|
441
455
|
script
|
@@ -528,7 +542,7 @@ exit $exit_status
|
|
528
542
|
#{meta_data}
|
529
543
|
|
530
544
|
# #{Log.color :green, "1. Prepare environment"}
|
531
|
-
#{prepare_environment}
|
545
|
+
#{prepare_environment(batch_options)}
|
532
546
|
env > #{batch_options[:fenv]}
|
533
547
|
|
534
548
|
# #{Log.color :green, "2. Execute"}
|
@@ -575,7 +589,7 @@ env > #{batch_options[:fenv]}
|
|
575
589
|
def run_job(job, options = {})
|
576
590
|
system = self.to_s.split("::").last
|
577
591
|
|
578
|
-
batch_base_dir, clean_batch_job, remove_batch_dir, procpath, tail, batch_dependencies, dry_run, orchestration_rules_file =
|
592
|
+
batch_base_dir, clean_batch_job, remove_batch_dir, procpath, tail, batch_dependencies, dry_run, orchestration_rules_file = IndiferentHash.process_options options,
|
579
593
|
:batch_base_dir, :clean_batch_job, :remove_batch_dir, :batch_procpath, :tail, :batch_dependencies, :dry_run, :orchestration_rules,
|
580
594
|
:batch_base_dir => File.expand_path(File.join('~/rbbt-batch'))
|
581
595
|
|
@@ -594,15 +608,15 @@ env > #{batch_options[:fenv]}
|
|
594
608
|
end
|
595
609
|
end
|
596
610
|
|
597
|
-
workflow = job.
|
598
|
-
task_name = job.
|
611
|
+
workflow = job.workflow
|
612
|
+
task_name = job.task_name
|
599
613
|
|
600
|
-
options =
|
614
|
+
options = IndiferentHash.setup(HPC::Orchestration.job_rules(HPC::Orchestration.orchestration_rules(orchestration_rules_file), job, true)).merge(options) if orchestration_rules_file
|
601
615
|
|
602
616
|
workflows_to_load = job.rec_dependencies.select{|d| Step === d}.collect{|d| d.workflow }.compact.collect(&:to_s) - [workflow.to_s]
|
603
617
|
|
604
618
|
TmpFile.with_file(nil, remove_batch_dir, :tmpdir => batch_base_dir, :prefix => "#{system}_rbbt_job-#{workflow.to_s}-#{task_name}-") do |batch_dir|
|
605
|
-
|
619
|
+
IndiferentHash.add_defaults options,
|
606
620
|
:batch_dir => batch_dir,
|
607
621
|
:inputs_dir => File.join(batch_dir, "inputs_dir"),
|
608
622
|
:workflows => workflows_to_load.any? ? workflows_to_load.uniq * "," : nil
|
@@ -638,6 +652,7 @@ env > #{batch_options[:fenv]}
|
|
638
652
|
end
|
639
653
|
|
640
654
|
def hold_dependencies(job, batch_job)
|
655
|
+
job.init_info
|
641
656
|
job.set_info :batch_job, batch_job
|
642
657
|
job.set_info :batch_system, self.batch_system
|
643
658
|
job.dependencies.each do |dep|
|
@@ -696,7 +711,7 @@ env > #{batch_options[:fenv]}
|
|
696
711
|
sleep 1
|
697
712
|
end
|
698
713
|
status_txt = job_status(job)
|
699
|
-
lines.times do
|
714
|
+
(lines + 1).times do
|
700
715
|
Log.clear_line(STDERR)
|
701
716
|
end
|
702
717
|
Log.clear_line(STDERR)
|
@@ -741,6 +756,10 @@ env > #{batch_options[:fenv]}
|
|
741
756
|
job_status(job).split(/[\s\.]+/).include?(job.to_s)
|
742
757
|
end
|
743
758
|
|
759
|
+
def jobs
|
760
|
+
job_status.split("\n").collect{|l| l.scan(/\d{5,}/).first}.compact.flatten.uniq
|
761
|
+
end
|
762
|
+
|
744
763
|
def wait_for_job(batch_dir, time = 1)
|
745
764
|
fexit = File.join(batch_dir, 'exit.status')
|
746
765
|
fjob = File.join(batch_dir, 'job.id')
|
data/lib/rbbt/hpc/lsf.rb
CHANGED
@@ -98,8 +98,8 @@ export BATCH_SYSTEM=#{batch_system}
|
|
98
98
|
return
|
99
99
|
elsif dry_run
|
100
100
|
STDERR.puts Log.color(:magenta, "To execute run: ") + Log.color(:blue, cmd)
|
101
|
-
STDERR.puts Log.color(:magenta, "To monitor progress run (needs local
|
102
|
-
raise HPC::
|
101
|
+
STDERR.puts Log.color(:magenta, "To monitor progress run (needs local scout): ") + Log.color(:blue, "scout lsf tail '#{batch_dir}'")
|
102
|
+
raise HPC::SBATCH, batch_dir
|
103
103
|
else
|
104
104
|
Open.rm fsync
|
105
105
|
Open.rm fexit
|
@@ -101,8 +101,8 @@ module HPC
|
|
101
101
|
|
102
102
|
batches.each do |batch|
|
103
103
|
job_rules = batch[:jobs].inject(nil) do |acc,job|
|
104
|
-
workflow = job.
|
105
|
-
task_name = job.
|
104
|
+
workflow = job.workflow
|
105
|
+
task_name = job.task_name
|
106
106
|
task_rules = task_specific_rules(rules, workflow, task_name)
|
107
107
|
acc = accumulate_rules(acc, task_rules.dup)
|
108
108
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module HPC
|
2
2
|
module Orchestration
|
3
3
|
def self.check_chains(chains, job)
|
4
|
-
return [] if Symbol === job.
|
4
|
+
return [] if Symbol === job.overriden_task
|
5
5
|
matches = []
|
6
6
|
chains.each do |name, chain|
|
7
|
-
workflow = job.
|
8
|
-
task_name = job.
|
7
|
+
workflow = job.overriden_workflow || job.workflow
|
8
|
+
task_name = job.overriden_workflow || job.task_name
|
9
9
|
next unless chain[:tasks].include?(workflow.to_s)
|
10
10
|
next unless chain[:tasks][workflow.to_s].include?(task_name.to_s)
|
11
11
|
matches << name
|
@@ -14,9 +14,28 @@ module HPC
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.parse_chains(rules)
|
17
|
-
return {} if rules["chains"].nil?
|
18
|
-
|
19
17
|
chains = IndiferentHash.setup({})
|
18
|
+
|
19
|
+
rules.each do |workflow,rules|
|
20
|
+
next unless rules["chains"]
|
21
|
+
rules["chains"].each do |name,rules|
|
22
|
+
rules = IndiferentHash.setup(rules.dup)
|
23
|
+
chain_tasks = rules.delete(:tasks).split(/,\s*/)
|
24
|
+
workflow = rules.delete(:workflow) if rules.include?(:workflow)
|
25
|
+
|
26
|
+
chain_tasks.each do |task|
|
27
|
+
chain_workflow, chain_task = task.split("#")
|
28
|
+
chain_task, chain_workflow = chain_workflow, workflow if chain_task.nil? or chain_tasks.empty?
|
29
|
+
|
30
|
+
chains[name] ||= IndiferentHash.setup({:tasks => {}, :rules => rules })
|
31
|
+
chains[name][:tasks][chain_workflow] ||= []
|
32
|
+
chains[name][:tasks][chain_workflow] << chain_task
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
return chains if rules["chains"].nil?
|
38
|
+
|
20
39
|
rules["chains"].each do |name,rules|
|
21
40
|
rules = IndiferentHash.setup(rules.dup)
|
22
41
|
chain_tasks = rules.delete(:tasks).split(/,\s*/)
|
@@ -32,6 +51,7 @@ module HPC
|
|
32
51
|
end
|
33
52
|
end
|
34
53
|
|
54
|
+
|
35
55
|
chains
|
36
56
|
end
|
37
57
|
|
@@ -65,8 +65,8 @@ module HPC
|
|
65
65
|
merge_rules(rules[workflow][task], workflow_rules)
|
66
66
|
end
|
67
67
|
|
68
|
-
def self.job_rules(rules, job)
|
69
|
-
return {} if job.done? or job.error?
|
68
|
+
def self.job_rules(rules, job, force = false)
|
69
|
+
return {} if (job.done? or job.error?) && ! force
|
70
70
|
job_rules = task_specific_rules(rules, job.workflow.to_s, job.task_name.to_s)
|
71
71
|
job.dependencies.each do |dep|
|
72
72
|
job_rules = accumulate_rules(job_rules, job_rules(rules, dep))
|
data/lib/rbbt/hpc/orchestrate.rb
CHANGED
@@ -14,12 +14,12 @@ module HPC
|
|
14
14
|
|
15
15
|
all_deps.each do |dep|
|
16
16
|
begin
|
17
|
-
|
17
|
+
dep.clean if (dep.error? && dep.recoverable_error?) ||
|
18
|
+
dep.aborted? || (dep.done? && dep.updated?)
|
18
19
|
rescue RbbtException
|
19
20
|
next
|
20
21
|
end
|
21
22
|
end
|
22
|
-
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.orchestration_rules(orchestration_rules_file = nil)
|
@@ -41,7 +41,7 @@ module HPC
|
|
41
41
|
IndiferentHash.setup(rules)
|
42
42
|
end
|
43
43
|
|
44
|
-
def orchestrate_job(job, options)
|
44
|
+
def orchestrate_job(job, options = {})
|
45
45
|
options.delete "recursive_clean"
|
46
46
|
options.delete "clean_task"
|
47
47
|
options.delete "clean"
|
@@ -65,7 +65,7 @@ module HPC
|
|
65
65
|
last_id = nil
|
66
66
|
last_dir = nil
|
67
67
|
while batches.any?
|
68
|
-
top = batches.select{|b| b[:deps].nil? || (b[:deps] - batch_ids.keys).empty? }.first
|
68
|
+
top = batches.select{|b| b[:deps].nil? || (b[:deps].collect{|d| d[:top_level]} - batch_ids.keys).empty? }.first
|
69
69
|
raise "No batch without unmet dependencies" if top.nil?
|
70
70
|
batches.delete top
|
71
71
|
|
@@ -78,16 +78,16 @@ module HPC
|
|
78
78
|
|
79
79
|
batch_dependencies = top[:deps].collect{|d|
|
80
80
|
target = d[:top_level]
|
81
|
-
canfail =
|
81
|
+
canfail = target.canfail?
|
82
82
|
|
83
|
-
top_jobs.each do |job|
|
84
|
-
|
85
|
-
end
|
83
|
+
#top_jobs.each do |job|
|
84
|
+
# canfail = true if job.canfail? # job.canfail_paths.include?(target.path)
|
85
|
+
#end
|
86
86
|
|
87
87
|
if canfail
|
88
|
-
'canfail:' + batch_ids[d].to_s
|
88
|
+
'canfail:' + batch_ids[d[:top_level]].to_s
|
89
89
|
else
|
90
|
-
batch_ids[d].to_s
|
90
|
+
batch_ids[d[:top_level]].to_s
|
91
91
|
end
|
92
92
|
}
|
93
93
|
end
|
@@ -99,11 +99,11 @@ module HPC
|
|
99
99
|
puts Log.color(:magenta, "Manifest: ") + Log.color(:blue, job_options[:manifest] * ", ") + " - tasks: #{job_options[:task_cpus] || 1} - time: #{job_options[:time]} - config: #{job_options[:config_keys]}"
|
100
100
|
puts Log.color(:yellow, "Deps: ") + Log.color(:blue, job_options[:batch_dependencies]*", ")
|
101
101
|
puts Log.color(:yellow, "Path: ") + top[:top_level].path
|
102
|
-
puts Log.color(:yellow, "Options: ") + job_options.inspect
|
103
|
-
batch_ids[top] = top[:top_level].task_signature
|
102
|
+
puts Log.color(:yellow, "Options: ") + job_options.reject{|k,v| k == :batch_dependencies || k == :manifest }.inspect
|
103
|
+
batch_ids[top[:top_level]] = top[:top_level].task_signature
|
104
104
|
else
|
105
105
|
id, dir = run_job(top[:top_level], job_options)
|
106
|
-
last_id = batch_ids[top] = id
|
106
|
+
last_id = batch_ids[top[:top_level]] = id
|
107
107
|
last_dir = dir
|
108
108
|
end
|
109
109
|
end
|
@@ -111,5 +111,11 @@ module HPC
|
|
111
111
|
[last_id, last_dir]
|
112
112
|
end
|
113
113
|
|
114
|
+
def produce_jobs(jobs, options = {})
|
115
|
+
jobs.each do |job|
|
116
|
+
self.orchestrate_job(job, options)
|
117
|
+
end
|
118
|
+
Step.wait_for_jobs jobs
|
119
|
+
end
|
114
120
|
end
|
115
121
|
end
|
data/lib/rbbt/hpc/slurm.rb
CHANGED
@@ -27,26 +27,26 @@ export BATCH_SYSTEM=#{batch_system}
|
|
27
27
|
def self.header(options = {})
|
28
28
|
options = options.dup
|
29
29
|
|
30
|
-
queue =
|
31
|
-
account =
|
32
|
-
partition =
|
33
|
-
task_cpus =
|
34
|
-
time =
|
35
|
-
nodes =
|
36
|
-
workdir =
|
37
|
-
exclusive =
|
38
|
-
highmem =
|
39
|
-
licenses =
|
40
|
-
constraint =
|
41
|
-
gres =
|
30
|
+
queue = IndiferentHash.process_options options, :queue
|
31
|
+
account = IndiferentHash.process_options options, :account
|
32
|
+
partition = IndiferentHash.process_options options, :partition
|
33
|
+
task_cpus = IndiferentHash.process_options options, :task_cpus
|
34
|
+
time = IndiferentHash.process_options options, :time
|
35
|
+
nodes = IndiferentHash.process_options options, :nodes
|
36
|
+
workdir = IndiferentHash.process_options options, :workdir
|
37
|
+
exclusive = IndiferentHash.process_options options, :exclusive
|
38
|
+
highmem = IndiferentHash.process_options options, :highmem
|
39
|
+
licenses = IndiferentHash.process_options options, :licenses
|
40
|
+
constraint = IndiferentHash.process_options options, :constraint
|
41
|
+
gres = IndiferentHash.process_options options, :gres
|
42
42
|
|
43
43
|
constraint = [constraint, "highmem"].compact * "&" if highmem
|
44
44
|
|
45
|
-
mem =
|
46
|
-
mem_per_cpu =
|
45
|
+
mem = IndiferentHash.process_options options, :mem
|
46
|
+
mem_per_cpu = IndiferentHash.process_options options, :mem_per_cpu
|
47
47
|
|
48
|
-
batch_dir =
|
49
|
-
batch_name =
|
48
|
+
batch_dir = IndiferentHash.process_options options, :batch_dir
|
49
|
+
batch_name = IndiferentHash.process_options options, :batch_name
|
50
50
|
|
51
51
|
fout = File.join(batch_dir, 'std.out')
|
52
52
|
ferr = File.join(batch_dir, 'std.err')
|
@@ -129,8 +129,8 @@ export BATCH_SYSTEM=#{batch_system}
|
|
129
129
|
return
|
130
130
|
elsif dry_run
|
131
131
|
STDERR.puts Log.color(:magenta, "To execute run: ") + Log.color(:blue, "sbatch '#{fcmd}'")
|
132
|
-
STDERR.puts Log.color(:magenta, "To monitor progress run (needs local
|
133
|
-
raise HPC::
|
132
|
+
STDERR.puts Log.color(:magenta, "To monitor progress run (needs local scout): ") + Log.color(:blue, "scout slurm tail '#{batch_dir}'")
|
133
|
+
raise HPC::SBATCH, batch_dir
|
134
134
|
else
|
135
135
|
Open.rm fsync
|
136
136
|
Open.rm fexit
|
@@ -39,7 +39,7 @@ class KnowledgeBase
|
|
39
39
|
def annotate(entities, type, database = nil)
|
40
40
|
format = @format[type] || type
|
41
41
|
entity_options = entity_options_for(type, database)
|
42
|
-
|
42
|
+
Entity.prepare_entity(entities, format, entity_options)
|
43
43
|
end
|
44
44
|
|
45
45
|
def translate(entities, type)
|
@@ -82,7 +82,7 @@ class KnowledgeBase
|
|
82
82
|
identifier_files.collect!{|f| f.annotate(f.gsub(/\bNAMESPACE\b/, namespace))} if namespace
|
83
83
|
identifier_files.collect!{|f| f.annotate(f.gsub(/\bNAMESPACE\b/, db_namespace(name)))} if not namespace and db_namespace(name)
|
84
84
|
identifier_files.reject!{|f| f.match(/\bNAMESPACE\b/)}
|
85
|
-
TSV.translation_index identifier_files, source(name),
|
85
|
+
TSV.translation_index identifier_files, nil, source(name), :persist => true
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
@@ -94,7 +94,7 @@ class KnowledgeBase
|
|
94
94
|
identifier_files.collect!{|f| f.annotate(f.gsub(/\bNAMESPACE\b/, namespace))} if self.namespace
|
95
95
|
identifier_files.collect!{|f| f.annotate(f.gsub(/\bNAMESPACE\b/, db_namespace(name)))} if namespace.nil? and db_namespace(name)
|
96
96
|
identifier_files.reject!{|f| f.match(/\bNAMESPACE\b/)}
|
97
|
-
TSV.translation_index identifier_files, target(name),
|
97
|
+
TSV.translation_index identifier_files, nil, target(name), :persist => true
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
@@ -102,7 +102,11 @@ class KnowledgeBase
|
|
102
102
|
return :all if entity == :all
|
103
103
|
index = source_index(name)
|
104
104
|
return entity if index.nil?
|
105
|
-
Array === entity
|
105
|
+
if Array === entity
|
106
|
+
entity.collect{|e| index[e] || e }
|
107
|
+
else
|
108
|
+
index[entity] || entity
|
109
|
+
end
|
106
110
|
end
|
107
111
|
|
108
112
|
|
@@ -110,7 +114,11 @@ class KnowledgeBase
|
|
110
114
|
return :all if entity == :all
|
111
115
|
index = target_index(name)
|
112
116
|
return entity if index.nil?
|
113
|
-
Array === entity
|
117
|
+
if Array === entity
|
118
|
+
entity.collect{|e| index[e] || e }
|
119
|
+
else
|
120
|
+
index[entity] || entity
|
121
|
+
end
|
114
122
|
end
|
115
123
|
|
116
124
|
def identify(name, entity)
|
@@ -17,11 +17,11 @@ class KnowledgeBase
|
|
17
17
|
when AnnotatedArray
|
18
18
|
format = entities.format if entities.respond_to? :format
|
19
19
|
format ||= entities.base_entity.to_s
|
20
|
-
{format => entities.
|
20
|
+
{format => entities.purge}
|
21
21
|
when Hash
|
22
22
|
entities
|
23
23
|
else
|
24
|
-
raise "Entities are not a Hash or an AnnotatedArray: #{
|
24
|
+
raise "Entities are not a Hash or an AnnotatedArray: #{Log.fingerprint entities}"
|
25
25
|
end
|
26
26
|
|
27
27
|
identify, identify_source, identify_target = entities.merge(options || {}).values_at :identify, :identify_source, :identify_target
|