rbbt-util 5.28.14 → 5.30.0
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.rb +1 -551
- data/lib/rbbt/hpc/orchestrate.rb +111 -0
- data/lib/rbbt/hpc/slurm.rb +603 -0
- data/lib/rbbt/persist.rb +4 -0
- data/lib/rbbt/persist/tsv/adapter.rb +48 -13
- data/lib/rbbt/util/cmd.rb +6 -1
- data/lib/rbbt/util/misc/inspect.rb +13 -3
- data/lib/rbbt/util/misc/options.rb +0 -42
- data/lib/rbbt/util/procpath.rb +49 -0
- data/lib/rbbt/workflow.rb +2 -1
- data/lib/rbbt/workflow/accessor.rb +7 -1
- data/lib/rbbt/workflow/examples.rb +2 -2
- data/lib/rbbt/workflow/step.rb +8 -5
- data/lib/rbbt/workflow/step/accessor.rb +28 -19
- data/lib/rbbt/workflow/step/dependencies.rb +1 -2
- data/lib/rbbt/workflow/step/run.rb +2 -5
- data/lib/rbbt/workflow/usage.rb +1 -1
- data/lib/rbbt/workflow/util/orchestrator.rb +14 -9
- data/lib/rbbt/workflow/util/provenance.rb +5 -2
- data/share/rbbt_commands/slurm/clean +165 -0
- data/share/rbbt_commands/slurm/list +220 -0
- data/share/rbbt_commands/slurm/orchestrate +48 -0
- data/share/rbbt_commands/{workflow/slurm → slurm/task} +11 -3
- data/share/rbbt_commands/tsv/slice +3 -3
- data/share/rbbt_commands/workflow/info +1 -1
- data/share/rbbt_commands/workflow/task +17 -7
- data/share/rbbt_commands/workflow/write_info +52 -0
- data/test/rbbt/test_workflow.rb +7 -7
- data/test/rbbt/util/test_procpath.rb +23 -0
- metadata +12 -3
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rbbt/util/simpleopt'
|
4
|
+
require 'rbbt/workflow'
|
5
|
+
require 'rbbt/workflow/usage'
|
6
|
+
require 'rbbt/hpc'
|
7
|
+
require 'rbbt/hpc/orchestrate'
|
8
|
+
require 'time'
|
9
|
+
|
10
|
+
$slurm_options = SOPT.get <<EOF
|
11
|
+
-dr--dry_run Print only the template
|
12
|
+
-cj--clean_job Clean job
|
13
|
+
--drbbt* Use development version of rbbt
|
14
|
+
-sing--singularity Use Singularity
|
15
|
+
-ug--user_group* Use alternative user group for group project directory
|
16
|
+
-c--contain* Contain in directory (using Singularity)
|
17
|
+
-s--sync* Contain in directory and sync jobs
|
18
|
+
-e--exclusive Make exclusive use of the node
|
19
|
+
-hm--highmem Make use of highmem cores
|
20
|
+
-wc--wipe_container* Wipe the jobs from the contain directory
|
21
|
+
-CS--contain_and_sync Contain and sync to default locations
|
22
|
+
-ci--copy_image When using a container directory, copy image there
|
23
|
+
-t--tail Tail the logs
|
24
|
+
-SPERF--SLURM_procpath* Save Procpath performance for SLURM job; specify only options
|
25
|
+
-q--queue* Queue
|
26
|
+
-t--task_cpus* Tasks
|
27
|
+
-W--workflows* Additional workflows
|
28
|
+
-tm--time* Time
|
29
|
+
-OR--orchestration_rules* Orchestration rules
|
30
|
+
-rmb--remove_slurm_basedir Remove the SLURM working directory (command, STDIN, exit status, ...)
|
31
|
+
EOF
|
32
|
+
|
33
|
+
class Step
|
34
|
+
def run(*args)
|
35
|
+
if done?
|
36
|
+
self.load
|
37
|
+
else
|
38
|
+
begin
|
39
|
+
Log.debug "Issuing SLURM job for #{self.path}"
|
40
|
+
HPC::SLURM.orchestrate_job(self, SOPT::GOT_OPTIONS.merge($slurm_options))
|
41
|
+
rescue HPC::SBATCH
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
ARGV.concat ["-W", $slurm_options[:workflows], '--detach'] if $slurm_options[:workflows]
|
48
|
+
load Rbbt.share.rbbt_commands.workflow.task.find
|
@@ -9,8 +9,9 @@ require 'time'
|
|
9
9
|
$slurm_options = SOPT.get <<EOF
|
10
10
|
-dr--dry_run Print only the template
|
11
11
|
-cj--clean_job Clean job
|
12
|
-
--drbbt Use development version of rbbt
|
12
|
+
--drbbt* Use development version of rbbt
|
13
13
|
-sing--singularity Use Singularity
|
14
|
+
-ug--user_group* Use alternative user group for group project directory
|
14
15
|
-c--contain* Contain in directory (using Singularity)
|
15
16
|
-s--sync* Contain in directory and sync jobs
|
16
17
|
-e--exclusive Make exclusive use of the node
|
@@ -19,10 +20,12 @@ $slurm_options = SOPT.get <<EOF
|
|
19
20
|
-CS--contain_and_sync Contain and sync to default locations
|
20
21
|
-ci--copy_image When using a container directory, copy image there
|
21
22
|
-t--tail Tail the logs
|
23
|
+
-SPERF--SLURM_procpath* Save Procpath performance for SLURM job; specify only options
|
22
24
|
-q--queue* Queue
|
23
25
|
-t--task_cpus* Tasks
|
26
|
+
-W--workflows* Additional workflows
|
24
27
|
-tm--time* Time
|
25
|
-
-
|
28
|
+
-rmb--remove_slurm_basedir Remove the SLURM working directory (command, STDIN, exit status, ...)
|
26
29
|
EOF
|
27
30
|
|
28
31
|
class Step
|
@@ -30,9 +33,14 @@ class Step
|
|
30
33
|
if done?
|
31
34
|
self.load
|
32
35
|
else
|
33
|
-
|
36
|
+
begin
|
37
|
+
Log.debug "Issuing SLURM job for #{self.path}"
|
38
|
+
HPC::SLURM.run_job(self, SOPT::GOT_OPTIONS.merge($slurm_options))
|
39
|
+
rescue HPC::SBATCH
|
40
|
+
end
|
34
41
|
end
|
35
42
|
end
|
36
43
|
end
|
37
44
|
|
45
|
+
ARGV.concat ["-W", $slurm_options[:workflows]] if $slurm_options[:workflows]
|
38
46
|
load Rbbt.share.rbbt_commands.workflow.task.find
|
@@ -35,7 +35,7 @@ file = case file
|
|
35
35
|
fields = options[:fields]
|
36
36
|
raise ParameterException, "Please specify the fields to slice" if fields.nil?
|
37
37
|
|
38
|
-
options[:header_hash]
|
38
|
+
options[:header_hash] ||= options["header_hash"]
|
39
39
|
|
40
40
|
case
|
41
41
|
when options[:tokyocabinet]
|
@@ -45,8 +45,8 @@ when options[:tokyocabinet_bd]
|
|
45
45
|
tsv = Persist.open_tokyocabinet(file, false, nil, TokyoCabinet::BDB)
|
46
46
|
puts tsv.summary
|
47
47
|
else
|
48
|
-
stream = TSV.traverse file, options.merge(:into => :stream, :type => :list, :
|
49
|
-
|
48
|
+
stream = TSV.traverse file, options.merge(:into => :stream, :type => :list, :fields => fields.split(","), :unnamed => true) do |k,fields,names|
|
49
|
+
[k,fields].flatten * "\t"
|
50
50
|
end
|
51
51
|
puts stream.read
|
52
52
|
exit 0
|
@@ -86,7 +86,7 @@ messages = info[:messages]
|
|
86
86
|
backtrace = info[:backtrace]
|
87
87
|
pid = info[:pid]
|
88
88
|
exception = info[:exception]
|
89
|
-
rest = info.keys - [:inputs, :dependencies, :status, :time_elapsed, :messages, :backtrace, :exception, :
|
89
|
+
rest = info.keys - [:inputs, :dependencies, :status, :time_elapsed, :messages, :backtrace, :exception, :archived_info]
|
90
90
|
|
91
91
|
|
92
92
|
puts Log.color(:magenta, "File") << ": " << step.path
|
@@ -20,7 +20,7 @@ def usage(workflow = nil, task = nil, exception=nil, abridge = false)
|
|
20
20
|
puts
|
21
21
|
if workflow.nil?
|
22
22
|
puts "No workflow specified. Use `rbbt workflow list` to list available workflows."
|
23
|
-
exit -1
|
23
|
+
exit! -1
|
24
24
|
end
|
25
25
|
|
26
26
|
if task.nil?
|
@@ -203,10 +203,11 @@ The `recursive_clean` cleans all the job dependency steps recursively.
|
|
203
203
|
-prec--prepare_cpus* Number of dependencies prepared in parallel
|
204
204
|
-rwt--remote_workflow_tasks* Load a yaml file describing remote workflow tasks
|
205
205
|
-od--override_deps* Override deps using 'Workflow#task=<path>' array_separated
|
206
|
+
-PERF--procpath_performance* Measure performance using procpath
|
206
207
|
EOF
|
207
208
|
|
208
209
|
workflow = ARGV.shift
|
209
|
-
usage and exit -1 if workflow.nil?
|
210
|
+
usage and exit! -1 if workflow.nil?
|
210
211
|
|
211
212
|
task = ARGV.shift
|
212
213
|
|
@@ -232,7 +233,8 @@ else
|
|
232
233
|
remote_workflows = {}
|
233
234
|
end
|
234
235
|
|
235
|
-
Workflow.workdir = Path.setup(File.expand_path(options.delete(:workdir_all))) if options[:workdir_all]
|
236
|
+
#Workflow.workdir = Path.setup(File.expand_path(options.delete(:workdir_all))) if options[:workdir_all]
|
237
|
+
Workflow.workdir.search_paths.merge!({:workdir => File.expand_path(options.delete(:workdir_all)), :default => :workdir }) if options[:workdir_all]
|
236
238
|
|
237
239
|
workflow = Workflow.require_workflow workflow
|
238
240
|
|
@@ -406,6 +408,13 @@ begin
|
|
406
408
|
exit 0
|
407
409
|
end
|
408
410
|
|
411
|
+
if options[:procpath_performance]
|
412
|
+
require 'rbbt/util/procpath'
|
413
|
+
job.fork
|
414
|
+
job.soft_grace
|
415
|
+
pid = job.info[:pid]
|
416
|
+
ProcPath.monitor(pid, options[:procpath_performance])
|
417
|
+
end
|
409
418
|
|
410
419
|
if do_fork
|
411
420
|
ENV["RBBT_NO_PROGRESS"] = "true"
|
@@ -422,7 +431,6 @@ begin
|
|
422
431
|
res = job
|
423
432
|
end
|
424
433
|
|
425
|
-
|
426
434
|
if options.delete(:printpath)
|
427
435
|
job.join
|
428
436
|
raise job.messages.last if (job.error? || job.aborted?) && job.messages
|
@@ -486,7 +494,7 @@ rescue ParameterException
|
|
486
494
|
puts
|
487
495
|
report_options saved_job_options
|
488
496
|
puts
|
489
|
-
exit -1
|
497
|
+
exit! -1
|
490
498
|
end
|
491
499
|
|
492
500
|
if options.delete(:list_job_files)
|
@@ -538,7 +546,7 @@ when Step
|
|
538
546
|
io.abort if io.respond_to? :abort
|
539
547
|
io.join if io.respond_to? :join
|
540
548
|
ensure
|
541
|
-
exit -1
|
549
|
+
exit! -1
|
542
550
|
end
|
543
551
|
rescue Exception
|
544
552
|
Log.exception $!
|
@@ -547,9 +555,11 @@ when Step
|
|
547
555
|
io.abort if io.respond_to? :abort
|
548
556
|
io.join if io.respond_to? :join
|
549
557
|
ensure
|
550
|
-
exit -1
|
558
|
+
exit! -1
|
551
559
|
end
|
552
560
|
end
|
561
|
+
elsif detach
|
562
|
+
exit! 0
|
553
563
|
else
|
554
564
|
res.join
|
555
565
|
out.puts Open.read(res.path) if Open.exist?(res.path) || Open.remote?(res.path) || Open.ssh?(res.path)
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rbbt/workflow'
|
4
|
+
|
5
|
+
require 'rbbt-util'
|
6
|
+
require 'rbbt-util'
|
7
|
+
require 'rbbt/util/simpleopt'
|
8
|
+
|
9
|
+
$0 = "rbbt #{$previous_commands*""} #{ File.basename(__FILE__) }" if $previous_commands
|
10
|
+
|
11
|
+
options = SOPT.setup <<EOF
|
12
|
+
Examine the info of a job result
|
13
|
+
|
14
|
+
$ rbbt workflow info <job-result> <key> <value>
|
15
|
+
|
16
|
+
-h--help Help
|
17
|
+
-f--force Write info even if key is already present
|
18
|
+
-r--recursive Write info for all dependencies as well
|
19
|
+
-p--check_pid Check that recursive jobs where created by the same process
|
20
|
+
EOF
|
21
|
+
|
22
|
+
SOPT.usage if options[:help]
|
23
|
+
|
24
|
+
file, key, value = ARGV
|
25
|
+
|
26
|
+
force, recursive, check_pid = options.values_at :force, :recursive, :check_pid
|
27
|
+
|
28
|
+
def get_step(file)
|
29
|
+
file = file.sub(/\.(info|files)/,'')
|
30
|
+
step = Workflow.load_step file
|
31
|
+
step
|
32
|
+
end
|
33
|
+
|
34
|
+
raise ParameterException if key.nil? || value.nil?
|
35
|
+
|
36
|
+
if %w(DELETE nil).include? value
|
37
|
+
value = nil
|
38
|
+
force = true
|
39
|
+
end
|
40
|
+
|
41
|
+
step = get_step file
|
42
|
+
|
43
|
+
step.set_info key, value if force || ! step.info.include?(key)
|
44
|
+
|
45
|
+
pid = step.info[:pid]
|
46
|
+
host = step.info[:pid_hostname]
|
47
|
+
|
48
|
+
step.rec_dependencies.each do |dep|
|
49
|
+
dep.set_info key, value if (force || ! dep.info.include?(key)) && (!check_pid || dep.info[:pid].to_s == pid and dep.info[:pid_hostname] == host)
|
50
|
+
rescue
|
51
|
+
Log.warn "Could no set info #{key} for #{dep.path}: #{$!.message}"
|
52
|
+
end if recursive
|
data/test/rbbt/test_workflow.rb
CHANGED
@@ -386,9 +386,9 @@ class TestWorkflow < Test::Unit::TestCase
|
|
386
386
|
job.run
|
387
387
|
Misc.with_env "RBBT_UPDATE", 'true' do
|
388
388
|
assert job.checks.select{|d| d.task_name.to_s == "t1" }.any?
|
389
|
-
job = TestWF.job(:t3)
|
390
|
-
job.step(:t1).clean
|
391
|
-
assert job.checks.select{|d| d.task_name.to_s == "t1" }.empty?
|
389
|
+
#job = TestWF.job(:t3)
|
390
|
+
#job.step(:t1).clean
|
391
|
+
#assert job.checks.select{|d| d.task_name.to_s == "t1" }.empty?
|
392
392
|
job = TestWF.job(:t3).recursive_clean
|
393
393
|
job.run
|
394
394
|
assert job.checks.select{|d| d.task_name.to_s == "t1" }.any?
|
@@ -427,7 +427,7 @@ class TestWorkflow < Test::Unit::TestCase
|
|
427
427
|
TmpFile.with_file do |dir|
|
428
428
|
Path.setup(dir)
|
429
429
|
Step.save_job_inputs(job, dir)
|
430
|
-
assert_equal Dir.glob(dir + "/*"), [dir.file.find + '.
|
430
|
+
assert_equal Dir.glob(dir + "/*"), [dir.file.find + '.yaml']
|
431
431
|
inputs = Workflow.load_inputs(dir, [:file], :file => :file)
|
432
432
|
assert_equal inputs, {:file => 'code'}
|
433
433
|
end
|
@@ -455,9 +455,9 @@ class TestWorkflow < Test::Unit::TestCase
|
|
455
455
|
job.run
|
456
456
|
Misc.with_env "RBBT_UPDATE", 'true' do
|
457
457
|
assert job.checks.select{|d| d.task_name.to_s == "t1" }.any?
|
458
|
-
job = TestWF.job(:t3)
|
459
|
-
job.step(:t1).clean
|
460
|
-
assert job.checks.select{|d| d.task_name.to_s == "t1" }.empty?
|
458
|
+
#job = TestWF.job(:t3)
|
459
|
+
#job.step(:t1).clean
|
460
|
+
#assert job.checks.select{|d| d.task_name.to_s == "t1" }.empty?
|
461
461
|
job = TestWF.job(:t3).recursive_clean
|
462
462
|
job.run
|
463
463
|
assert job.checks.select{|d| d.task_name.to_s == "t1" }.any?
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'test_helper.rb')
|
2
|
+
require 'rbbt/util/procpath'
|
3
|
+
|
4
|
+
class TestProcPath < Test::Unit::TestCase
|
5
|
+
def test_record_and_plot
|
6
|
+
Log.with_severity 0 do
|
7
|
+
pid = Process.fork do
|
8
|
+
a = ""
|
9
|
+
(0..1000).each do
|
10
|
+
a << (0..rand(10000).to_i).to_a.collect{|i| "TEST #{i}" } * " "
|
11
|
+
sleep 0.1
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
TmpFile.with_file(nil, false) do |db|
|
16
|
+
|
17
|
+
ProcPath.record(pid, db, :interval => '1', "recnum" => 100)
|
18
|
+
ProcPath.plot(db, db + '.svg', "moving-average-window" => 1 )
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
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.
|
4
|
+
version: 5.30.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Vazquez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -211,6 +211,8 @@ files:
|
|
211
211
|
- lib/rbbt/entity/identifiers.rb
|
212
212
|
- lib/rbbt/fix_width_table.rb
|
213
213
|
- lib/rbbt/hpc.rb
|
214
|
+
- lib/rbbt/hpc/orchestrate.rb
|
215
|
+
- lib/rbbt/hpc/slurm.rb
|
214
216
|
- lib/rbbt/knowledge_base.rb
|
215
217
|
- lib/rbbt/knowledge_base/enrichment.rb
|
216
218
|
- lib/rbbt/knowledge_base/entity.rb
|
@@ -298,6 +300,7 @@ files:
|
|
298
300
|
- lib/rbbt/util/misc/system.rb
|
299
301
|
- lib/rbbt/util/named_array.rb
|
300
302
|
- lib/rbbt/util/open.rb
|
303
|
+
- lib/rbbt/util/procpath.rb
|
301
304
|
- lib/rbbt/util/python.rb
|
302
305
|
- lib/rbbt/util/semaphore.rb
|
303
306
|
- lib/rbbt/util/simpleDSL.rb
|
@@ -376,6 +379,10 @@ files:
|
|
376
379
|
- share/rbbt_commands/resource/produce
|
377
380
|
- share/rbbt_commands/resource/read
|
378
381
|
- share/rbbt_commands/rsync
|
382
|
+
- share/rbbt_commands/slurm/clean
|
383
|
+
- share/rbbt_commands/slurm/list
|
384
|
+
- share/rbbt_commands/slurm/orchestrate
|
385
|
+
- share/rbbt_commands/slurm/task
|
379
386
|
- share/rbbt_commands/stat/abs
|
380
387
|
- share/rbbt_commands/stat/boxplot
|
381
388
|
- share/rbbt_commands/stat/compare_lists
|
@@ -430,9 +437,9 @@ files:
|
|
430
437
|
- share/rbbt_commands/workflow/remote/list
|
431
438
|
- share/rbbt_commands/workflow/remote/remove
|
432
439
|
- share/rbbt_commands/workflow/server
|
433
|
-
- share/rbbt_commands/workflow/slurm
|
434
440
|
- share/rbbt_commands/workflow/task
|
435
441
|
- share/rbbt_commands/workflow/trace
|
442
|
+
- share/rbbt_commands/workflow/write_info
|
436
443
|
- share/unicorn.rb
|
437
444
|
- share/workflow_config.ru
|
438
445
|
- test/rbbt/annotations/test_util.rb
|
@@ -511,6 +518,7 @@ files:
|
|
511
518
|
- test/rbbt/util/test_log.rb
|
512
519
|
- test/rbbt/util/test_misc.rb
|
513
520
|
- test/rbbt/util/test_open.rb
|
521
|
+
- test/rbbt/util/test_procpath.rb
|
514
522
|
- test/rbbt/util/test_python.rb
|
515
523
|
- test/rbbt/util/test_semaphore.rb
|
516
524
|
- test/rbbt/util/test_simpleDSL.rb
|
@@ -558,6 +566,7 @@ test_files:
|
|
558
566
|
- test/rbbt/workflow/test_task.rb
|
559
567
|
- test/rbbt/resource/test_path.rb
|
560
568
|
- test/rbbt/util/test_colorize.rb
|
569
|
+
- test/rbbt/util/test_procpath.rb
|
561
570
|
- test/rbbt/util/misc/test_omics.rb
|
562
571
|
- test/rbbt/util/misc/test_pipes.rb
|
563
572
|
- test/rbbt/util/misc/test_format.rb
|