modified: makefile
[GalaxyCodeBases.git] / tools / lh3misc / sys / asub
blob59d215ebba3a0fdf67eab39b73bd5b89805d567c
1 #!/usr/bin/perl -w
3 # Author: lh3
5 use strict;
6 use warnings;
7 use Getopt::Std;
8 use Cwd qw/abs_path/;
9 use Sys::Hostname qw/hostname/;
11 my $version = "0.1.8";
13 my %opts = (R=>'', j=>'', k=>0, q=>'', c=>'', w=>'', M=>'', n=>'', m=>'', W=>'');
14 getopts('R:j:k:q:c:pw:M:n:m:W:', \%opts);
15 &usage if (-t STDIN && @ARGV == 0);
16 my $is_run = ($opts{k} > 0 && $opts{j})? 1 : 0;
17 if (!$is_run) { # prepare to run
18 my $is_sge = &which('bsub')? 0 : 1;
19 $opts{j} ||= sprintf("asub_$$%.3d", rand(1000));
20 my ($fh, $K);
21 $K = 0;
22 open($fh, ">$opts{j}.sh") || die;
23 while (<>) {
24 s/&\s*$//; # remove "&" at the end of the command
25 next if (/^\s*$/);
26 print $fh $_;
27 ++$K;
29 close($fh);
30 $_ = $opts{j};
31 my $cmd;
32 $opts{c} = $K if ($opts{c} && $opts{c} > $K);
33 $opts{q} = qq/-q $opts{q}/ if ($opts{q});
34 if (!$is_sge) { # LSF
35 $opts{R} = qq/-R "$opts{R}"/ if ($opts{R});
36 $opts{c} = qq/\%$opts{c}/ if ($opts{c});
37 $opts{w} = qq/-w "$opts{w}"/ if ($opts{w});
38 $opts{n} = qq/-n $opts{n}/ if ($opts{n});
39 $opts{m} = qq/-m $opts{m}/ if ($opts{m});
40 $opts{W} = qq/-W $opts{W}/ if ($opts{W});
41 if ($opts{n}) {
42 if ($opts{R}) {
43 chop($opts{R}); # chop the tailing "
44 $opts{R} .= qq/ span[hosts=1]"/;
45 } else {
46 $opts{R} = qq/-R "span[hosts=1]"/;
49 if ($opts{M}) {
50 if ($opts{R}) {
51 chop($opts{R}); # chop the tailing "
52 $opts{R} .= qq/ select[mem>$opts{M}] rusage[mem=$opts{M}]"/;
53 } else {
54 $opts{R} = qq/-R "select[mem>$opts{M}] rusage[mem=$opts{M}]"/;
56 $opts{R} .= ' -M ' . ($opts{M}*1000);
58 $cmd = qq(mkdir -p $_.out $_.err && echo '$0 -j $_.sh -k \${LSB_JOBINDEX}' | bsub -J$_)
59 . qq("[1-$K]$opts{c}" -o $_.out/\%I.out -e $_.err/\%I.err $opts{n} $opts{R} $opts{q} $opts{w} $opts{m} $opts{W});
60 } else { # SGE
61 $opts{R} = qq/-l "$opts{R}"/ if ($opts{R});
62 $opts{w} = qq/-hold_jid $opts{w}/ if ($opts{w});
63 my $asub = abs_path($0);
64 $cmd = qq(mkdir -p $_.out $_.err && echo '$asub -j $_.sh -k \${SGE_TASK_ID}' | qsub -N $_ -cwd )
65 . qq(-t 1-$K -o '$_.out/\$TASK_ID.out' -e '$_.err/\$TASK_ID.err' $opts{R} $opts{q} $opts{w});
67 defined($opts{p})? (print "$cmd\n") : system($cmd);
68 } else { # run the command
69 warn("[asub] Hostname: ".hostname.", Arch-OS: ".&get_cpu_sys."\n");
70 my $fh;
71 my $k = 0;
72 open($fh, $opts{j}) || die;
73 while (<$fh>) {
74 chomp;
75 last if ((++$k) == $opts{k});
77 my $cmd = $_;
78 close($fh);
79 warn("[asub] Command: $_\n");
80 warn("[asub] --- BEGIN OF COMMAND STDERR ---\n");
81 my $ret = system($_);
82 warn("[asub] --- END OF COMMAND STDERR ---\n");
83 warn("[asub] Return value: $ret\n");
84 exit($ret);
87 sub get_cpu_sys {
88 my $dir = `uname -p 2>/dev/null`;
89 $dir = `uname -m 2>/dev/null` if (!$dir || $dir =~ "unknown");
90 $dir .= '-'.`uname -s`;
91 $dir = lc($dir);
92 $dir =~ s/\s//g;
93 return $dir;
96 sub which {
97 my $file = shift;
98 my $path = (@_)? shift : $ENV{PATH};
99 return if (!defined($path));
100 foreach my $x (split(":", $path)) {
101 $x =~ s/\/$//;
102 return "$x/$file" if (-x "$x/$file");
104 return;
107 sub usage {
108 die qq(
109 Program: asub (Array Job submission with bsub/qsub)
110 Version: $version
111 Contact: Heng Li <lh3\@sanger.ac.uk>\n
112 Usage: asub [options] <cmd_file>\n
113 Options: -R STR resources string [null]
114 -w STR job dependency [null]
115 -q STR queue name [default queue]
116 -j STR job name [auto]
117 -c INT number of processors (LSF only) [max]
118 -M INT maximum memory in MB (Sanger LSF only) [null]
119 -W INT runtime limit (LSF only) [none]
120 -n INT # CPUs for a parallel job (LSF only) [null]
121 -m STR host group (LSF only) [null]
122 -p print the submission command only
124 Note: For option -R and -w, SGE and LSF have different syntax. Please
125 check SGE/LSF manual page for details. Here are some examples for
126 LSF:
128 -R "select[type==X86_64&&mem>800] rusage[mem=800]"
129 -w "done(my_job_001)"
131 And for SGE:
133 -R h_cpu=86400,h_data=1000000000
134 -w my_job_001