-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmake_jobs.pl
186 lines (164 loc) · 5.99 KB
/
make_jobs.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#!/usr/bin/perl
# /usr/bin/time make combined/mpos43918.ms/__COMBINED__fixed_colours.grb.sol
#HACK: For some reason, qsub chokes if I try to add these lines to the scripts:
#\$ -o $dir
#\$ -e $dir
# For convenient use with -s.
sub cmpCanon($$) {
if ($_[0] =~ /\.canon\z/) {
if ($_[1] =~ /\.canon\z/) {
return 0;
} else {
return 1;
}
} elsif ($_[1] =~ /\.canon\z/) {
return -1;
} else {
return 0;
}
}
# Put bigger single-digit reductions *earlier*, since they're more likely to *solve* to completion.
sub gradeReduction($) {
my ($d) = @_;
$d = 0 if !length $d; #HACK: Don't know what to do with it actually
$d = 9 - $d if length $d == 1;
return $d;
}
sub cmpReduce($$) {
if (my ($d1) = $_[0] =~ /\.reduced(\d*)/) {
if (my ($d2) = $_[1] =~ /\.reduced(\d*)/) {
return gradeReduction($d1) <=> gradeReduction($d2);
} else {
return -1;
}
} elsif ($_[1] =~ /\.reduced(\d*)/) {
return 1;
} else {
return 0;
}
}
#my $transformExpr = ""; # Do nothing
my @transformExprs;
#if (@ARGV && $ARGV[0] eq '-t') {
# shift;
# $transformExpr = shift;
#}
my $filterExpr = 1; # If true, a file will be considered, otherwise it will be skipped.
my $jobNameExpr = 's!([^/]+)\z!make.$1.sh!'; # Used by default to decide which job filename to put a given target file's make command into. If more than one target maps to the same job filename, they will appear as separate commands in that file (in unspecified order).
my $sortExpr = 'cmpCanon($a, $b) or cmpReduce($a, $b) or $a cmp $b'; # Used by default to put targets ending with .canon last, then targets containing .reduce last, then alphabetically.
#my @files = @ARGV;
my @files;
my $dryRun = 0;
my @makeOptions; # Extra arguments that will be passed to each make invocation (e.g. variable settings)
# Default to reading filenames from the command line. Can be changed with -i.
my $get_next_file = sub { $_ = shift @files; };
my $readingFNamesFromStdin = 0;
# Process command-line arguments
while (@ARGV) {
$_ = shift;
if ($_ eq '-t') {
#$transformExpr = shift;
push @transformExprs, shift;
} elsif ($_ eq '-f') {
$filterExpr = shift;
} elsif ($_ eq '-j') {
$jobNameExpr = shift;
} elsif ($_ eq '-n' || $_ eq '--dry-run') {
$dryRun = 1;
print STDERR "Dry run only -- no job files will actually be created.\n";
} elsif ($_ eq '-O' || $_ eq '--make-option') {
push @makeOptions, shift;
} elsif ($_ eq '-i' || $_ eq '--from-stdin') {
$get_next_file = sub { $_ = <>; if (defined) { chomp; s/\r\z//; } $_ };
$readingFNamesFromStdin = 1;
print STDERR "Will read files from STDIN instead of the command line.\n";
} elsif ($_ eq '--') {
push @files, @ARGV;
last;
} elsif (/\A-/) {
die "Unrecognised option '$_'.";
} else {
push @files, $_;
}
}
push @transformExprs, "" if !@transformExprs; # If no transformations were specified, default to a single no-op.
my $makeOptionsStr = join(' ', map { my $x = $_; $x =~ s/(\W)/\\$1/g; $x } @makeOptions);
print STDERR "Transform expressions (-t):\n";
foreach (@transformExprs) {
print STDERR "<$_>\n";
}
print STDERR "Filter expression (-f): <$filterExpr>\n";
print STDERR "Job filename expression (-j): <$jobNameExpr>\n";
print STDERR "Extra options to pass to make: <$makeOptionsStr>\n";
print STDERR "You didn't specify -i but there are no files on the command line: nothing to do!\n" if !@files && !$readingFNamesFromStdin;
sub poor_mans_realpath($) {
chomp(my $x = `cd '$_[0]' && pwd`); #HACK: Ugh.
return $x;
}
# Should be run from /home/xe53kiw/frag_tree_reduction, otherwise the makefile rules won't work.
my $cwd = `pwd`;
chomp $cwd;
die "You should really run this from /home/xe53kiw/frag_tree_reduction -- if you're sure you know what you're doing, disable this die() call and rerun." if $cwd ne '/home/xe53kiw/frag_tree_reduction'; #HACK
@files = glob "combined/mpos*.ms/__COMBINED__.txt" if !@files;
my %targets; # @{$targets{"some_job_name.sh"}} is a list of targets that will be made by the job script "some_job_name.sh".
#foreach (<combined/mpos*.ms/__COMBINED__.txt>) {
#foreach (@files) {
#foreach (grep { eval $filterExpr } @files) {
while (defined $get_next_file->()) { # Reads the next filename into $_, from either the command line or STDIN
next if !eval $filterExpr;
#my ($job) = m!/(mpos.*?)/! or die;
#my $job = $_;
#$job =~ s!.*?/!!;
#$job =~ tr!/!_!;
my $kludge = /__COMBINED__/ ? "fixed_colours" : ""; #HACK
# s/\.txt$/$kludge.grb.sol.canon/ or die;
# eval($transformExpr); # This is where you need to transform the current filename
my $savedCopy = $_;
foreach my $tExpr (@transformExprs) {
$_ = $savedCopy;
eval($tExpr); # This is where you need to transform the current filename
#print STDERR "<$_>. job=<$job>\n";
#open my $jobF, ">", "do_orig_$job.sh" or die;
#open my $jobF, ">", "$dir/do_orig_$job.sh" or die;
my $jobFn = $_;
# $jobFn =~ s!([^/]+)\z!make.$1.sh!;
# print STDERR "Writing job script file '$jobFn'...\n";
foreach ($jobFn) { # This foreach allows the job name transformation to be conveniently done on $_ :)
eval($jobNameExpr);
}
print STDERR "Adding make command for target '$_' to job script file '$jobFn'...\n";
push @{$targets{$jobFn}}, $_;
}
}
# Now actually generate the job scripts
foreach my $jobFn (keys %targets) {
print STDERR "Writing " . scalar(@{$targets{$jobFn}}) . " make commands to job script file '$jobFn'...\n";
my ($dir, $bn) = $jobFn =~ m!\A(.*)/(.*)\z!;
if (!defined $dir) {
$dir = ".";
$bn = $_;
}
my $absDir = poor_mans_realpath $dir; # Necessary because SGE uses $HOME-relative paths for -o and -e!
if (!$dryRun) {
open my $jobF, ">", $jobFn or die;
print $jobF <<THE_END;
#!/bin/sh
#\$ -wd $absDir
#\$ -o .
#\$ -e .
echo Host: `hostname`
cd $cwd
export PATH=\$PATH:.
echo Date:
date
echo Environment:
env
trap 'echo "Caught SIGUSR2, will be terminated soon!"' USR2
THE_END
#foreach (@{$targets{$jobFn}}) {
foreach (sort { eval($sortExpr) } @{$targets{$jobFn}}) { # $a and $b appear to be visible to the eval'ed expression, thank God
print $jobF "/usr/bin/time make $makeOptionsStr $_\n";
}
close $jobF;
}
}