line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package HPC::Runner::Command::submit_jobs::Utils::Scheduler::Submit; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
828
|
use Moose::Role; |
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
13
|
|
4
|
1
|
|
|
1
|
|
8541
|
use Cwd; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
97
|
|
5
|
1
|
|
|
1
|
|
11
|
use IPC::Open3; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
64
|
|
6
|
1
|
|
|
1
|
|
11
|
use IO::Select; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
59
|
|
7
|
1
|
|
|
1
|
|
9
|
use Symbol; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
72
|
|
8
|
1
|
|
|
1
|
|
10
|
use Try::Tiny; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
1485
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=head3 process_submit_command |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
splitting this off from the main command |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
DEPRACATED process_batch_command |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
Command that hpcrunner.pl execute_job/execute_array uses |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
=cut |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
sub process_submit_command { |
21
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
22
|
0
|
|
|
|
|
|
my $counter = shift; |
23
|
|
|
|
|
|
|
|
24
|
0
|
|
|
|
|
|
my $command = ""; |
25
|
|
|
|
|
|
|
|
26
|
0
|
|
|
|
|
|
my $logname = $self->create_log_name($counter); |
27
|
|
|
|
|
|
|
|
28
|
0
|
|
|
|
|
|
$self->jobs->{ $self->current_job }->add_lognames($logname); |
29
|
|
|
|
|
|
|
|
30
|
0
|
|
|
|
|
|
$command = "sleep 20\n"; |
31
|
0
|
|
|
|
|
|
$command .= "cd " . getcwd() . "\n"; |
32
|
0
|
0
|
|
|
|
|
if ( $self->has_custom_command ) { |
33
|
0
|
|
|
|
|
|
$command .= $self->custom_command . " \\\n"; |
34
|
|
|
|
|
|
|
} |
35
|
|
|
|
|
|
|
else { |
36
|
0
|
|
|
|
|
|
$command .= "hpcrunner.pl " . $self->subcommand . " \\\n"; |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
|
39
|
0
|
0
|
|
|
|
|
$command .= "\t--project " . $self->project . " \\\n" if $self->has_project; |
40
|
|
|
|
|
|
|
|
41
|
0
|
|
|
|
|
|
my $batch_index_start = $self->gen_batch_index_str; |
42
|
|
|
|
|
|
|
|
43
|
0
|
|
|
|
|
|
my $log = ""; |
44
|
0
|
0
|
|
|
|
|
if ( $self->no_log_json ) { |
45
|
0
|
|
|
|
|
|
$log = "\t--no_log_json \\\n"; |
46
|
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
$command .= |
49
|
|
|
|
|
|
|
"\t--infile " |
50
|
|
|
|
|
|
|
. $self->cmdfile . " \\\n" |
51
|
|
|
|
|
|
|
. "\t--outdir " |
52
|
|
|
|
|
|
|
. $self->outdir . " \\\n" |
53
|
|
|
|
|
|
|
. "\t--commands " |
54
|
|
|
|
|
|
|
. $self->jobs->{ $self->current_job }->commands_per_node . " \\\n" |
55
|
|
|
|
|
|
|
. "\t--batch_index_start " |
56
|
|
|
|
|
|
|
. $self->gen_batch_index_str . " \\\n" |
57
|
|
|
|
|
|
|
. "\t--procs " |
58
|
0
|
|
|
|
|
|
. $self->jobs->{ $self->current_job }->procs . " \\\n" |
59
|
|
|
|
|
|
|
. "\t--logname " |
60
|
|
|
|
|
|
|
. $logname . " \\\n" |
61
|
|
|
|
|
|
|
. $log |
62
|
|
|
|
|
|
|
. "\t--data_tar " |
63
|
|
|
|
|
|
|
. $self->data_tar . " \\\n" |
64
|
|
|
|
|
|
|
. "\t--process_table " |
65
|
|
|
|
|
|
|
. $self->process_table; |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
#TODO Update metastring to give array index |
68
|
|
|
|
|
|
|
my $metastr = |
69
|
|
|
|
|
|
|
$self->job_stats->create_meta_str( $counter, $self->batch_counter, |
70
|
|
|
|
|
|
|
$self->current_job, $self->use_batches, |
71
|
0
|
|
|
|
|
|
$self->jobs->{ $self->current_job } ); |
72
|
|
|
|
|
|
|
|
73
|
0
|
0
|
|
|
|
|
$command .= " \\\n\t" if $metastr; |
74
|
0
|
0
|
|
|
|
|
$command .= $metastr if $metastr; |
75
|
|
|
|
|
|
|
|
76
|
0
|
|
|
|
|
|
my $pluginstr = $self->create_plugin_str; |
77
|
0
|
0
|
|
|
|
|
$command .= $pluginstr if $pluginstr; |
78
|
|
|
|
|
|
|
|
79
|
0
|
|
|
|
|
|
my $version_str = $self->create_version_str; |
80
|
0
|
0
|
|
|
|
|
$command .= $version_str if $version_str; |
81
|
|
|
|
|
|
|
|
82
|
0
|
|
|
|
|
|
$command .= "\n\n"; |
83
|
0
|
|
|
|
|
|
return $command; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub create_log_name { |
87
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
88
|
0
|
|
|
|
|
|
my $counter = shift; |
89
|
|
|
|
|
|
|
|
90
|
0
|
|
|
|
|
|
my $logname; |
91
|
|
|
|
|
|
|
|
92
|
0
|
0
|
|
|
|
|
if ( $self->has_project ) { |
93
|
0
|
|
|
|
|
|
$logname = $self->project . "_" . $counter . "_" . $self->current_job; |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
else { |
96
|
0
|
|
|
|
|
|
$logname = $counter . "_" . $self->current_job; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
0
|
|
|
|
|
|
return $logname; |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=head3 create_version_str |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
If there is a version add it |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=cut |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
#TODO Move to git |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
sub create_version_str { |
111
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
112
|
|
|
|
|
|
|
|
113
|
0
|
|
|
|
|
|
my $version_str = ""; |
114
|
|
|
|
|
|
|
|
115
|
0
|
0
|
0
|
|
|
|
if ( $self->has_git && $self->has_version ) { |
116
|
0
|
|
|
|
|
|
$version_str .= " \\\n\t"; |
117
|
0
|
|
|
|
|
|
$version_str .= "--version " . $self->version; |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
0
|
|
|
|
|
|
return $version_str; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=head3 process_template |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=cut |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
sub process_template { |
128
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
129
|
0
|
|
|
|
|
|
my $counter = shift; |
130
|
0
|
|
|
|
|
|
my $command = shift; |
131
|
0
|
|
|
|
|
|
my $ok = shift; |
132
|
0
|
|
|
|
|
|
my $array_str = shift; |
133
|
|
|
|
|
|
|
|
134
|
0
|
|
|
|
|
|
my $jobname = $self->resolve_project($counter); |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
$self->template->process( |
137
|
|
|
|
|
|
|
$self->template_file, |
138
|
|
|
|
|
|
|
{ |
139
|
|
|
|
|
|
|
JOBNAME => $jobname, |
140
|
|
|
|
|
|
|
USER => $self->user, |
141
|
|
|
|
|
|
|
COMMAND => $command, |
142
|
|
|
|
|
|
|
ARRAY_STR => $array_str, |
143
|
|
|
|
|
|
|
AFTEROK => $ok, |
144
|
|
|
|
|
|
|
MODULES => $self->jobs->{ $self->current_job }->join_modules(' '), |
145
|
|
|
|
|
|
|
OUT => $self->logdir |
146
|
|
|
|
|
|
|
. "/$counter" . "_" |
147
|
|
|
|
|
|
|
. $self->current_job . ".log", |
148
|
0
|
0
|
|
|
|
|
job => $self->jobs->{ $self->current_job }, |
149
|
|
|
|
|
|
|
}, |
150
|
|
|
|
|
|
|
$self->slurmfile |
151
|
|
|
|
|
|
|
) || die $self->template->error; |
152
|
|
|
|
|
|
|
|
153
|
0
|
|
|
|
|
|
chmod 0777, $self->slurmfile; |
154
|
|
|
|
|
|
|
|
155
|
0
|
|
|
|
|
|
my $scheduler_id; |
156
|
|
|
|
|
|
|
try { |
157
|
0
|
|
|
0
|
|
|
$scheduler_id = $self->submit_jobs; |
158
|
0
|
|
|
|
|
|
}; |
159
|
|
|
|
|
|
|
|
160
|
0
|
|
|
|
|
|
$DB::single = 2; |
161
|
0
|
0
|
|
|
|
|
if ( defined $scheduler_id ) { |
162
|
0
|
|
|
|
|
|
$self->jobs->{ $self->current_job }->add_scheduler_ids($scheduler_id); |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
else { |
165
|
0
|
|
|
|
|
|
$self->jobs->{ $self->current_job }->add_scheduler_ids('000xxx'); |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=head3 submit_to_scheduler |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
Submit the job to the scheduler. |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
Inputs: self, submit_command (sbatch, qsub, etc) |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
Returns: exitcode, stdout, stderr |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
This subroutine was just about 100% from the following perlmonks discussions. All that I did was add in some logging. |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
http://www.perlmonks.org/?node_id=151886 |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
This is probably overkill - but occasionally the scheduler takes longer than we think to exit |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
=cut |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
sub submit_to_scheduler { |
186
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
187
|
0
|
|
|
|
|
|
my $submit_command = shift; |
188
|
|
|
|
|
|
|
|
189
|
0
|
|
|
|
|
|
my ( $infh, $outfh, $errfh, $exitcode, $cmdpid, $stdout, $stderr ); |
190
|
0
|
|
|
|
|
|
$errfh = gensym(); |
191
|
0
|
|
|
|
|
|
eval { |
192
|
|
|
|
|
|
|
|
193
|
0
|
|
|
|
|
|
$cmdpid = open3( $infh, $outfh, $errfh, $submit_command ); |
194
|
|
|
|
|
|
|
}; |
195
|
0
|
0
|
|
|
|
|
if ($@) { |
196
|
0
|
|
|
|
|
|
$exitcode = $?; |
197
|
0
|
|
|
|
|
|
$stderr = $@; |
198
|
0
|
|
|
|
|
|
$cmdpid = 0; |
199
|
0
|
|
|
|
|
|
$self->app_log->fatal( 'Cmd failed : ' . $submit_command ); |
200
|
0
|
|
|
|
|
|
$self->app_log->fatal($@); |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
0
|
|
|
|
|
|
$infh->autoflush(); |
204
|
0
|
0
|
|
|
|
|
return [ $exitcode, '', $stderr, ] if $exitcode; |
205
|
|
|
|
|
|
|
|
206
|
0
|
|
|
|
|
|
my $sel = new IO::Select; # create a select object |
207
|
0
|
|
|
|
|
|
$sel->add( $outfh, $errfh ); # and add the fhs |
208
|
|
|
|
|
|
|
|
209
|
0
|
|
|
|
|
|
while ( my @ready = $sel->can_read ) { |
210
|
0
|
|
|
|
|
|
foreach my $fh (@ready) { # loop through them |
211
|
0
|
|
|
|
|
|
my $line; |
212
|
0
|
|
|
|
|
|
my $len = sysread $fh, $line, 4096; |
213
|
0
|
0
|
|
|
|
|
next unless defined $len; |
214
|
0
|
0
|
|
|
|
|
if ( $len == 0 ) { |
215
|
0
|
|
|
|
|
|
$sel->remove($fh); |
216
|
0
|
|
|
|
|
|
close($fh); |
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
else { # we read data alright |
219
|
0
|
0
|
|
|
|
|
if ( $fh == $outfh ) { |
|
|
0
|
|
|
|
|
|
220
|
0
|
|
|
|
|
|
$stdout .= $line; |
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
elsif ( $fh == $errfh ) { |
223
|
0
|
|
|
|
|
|
$stderr .= $line; |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
} |
228
|
|
|
|
|
|
|
|
229
|
0
|
0
|
|
|
|
|
waitpid( $cmdpid, 1 ) if $cmdpid; |
230
|
0
|
|
|
|
|
|
$exitcode = $?; |
231
|
|
|
|
|
|
|
|
232
|
0
|
|
|
|
|
|
$sel->remove($outfh); |
233
|
0
|
|
|
|
|
|
$sel->remove($infh); |
234
|
|
|
|
|
|
|
|
235
|
0
|
|
|
|
|
|
return ( $exitcode, $stdout, $stderr ); |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
sub job_failure { |
239
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
240
|
|
|
|
|
|
|
|
241
|
0
|
|
|
|
|
|
$self->log->warn( "Submit scripts will be written, " |
242
|
|
|
|
|
|
|
. "but will not be submitted to the queue." ); |
243
|
0
|
|
|
|
|
|
$self->log->warn( |
244
|
|
|
|
|
|
|
"Any pending jobs that depend upon this job will NOT be submitted to the queue." |
245
|
|
|
|
|
|
|
); |
246
|
0
|
|
|
|
|
|
$self->log->warn( |
247
|
|
|
|
|
|
|
"Please look at your submission scripts in " . $self->outdir ); |
248
|
0
|
|
|
|
|
|
$self->log->warn( |
249
|
|
|
|
|
|
|
"And your logs in " . $self->logdir . "\nfor more information" ); |
250
|
0
|
|
|
|
|
|
$self->log->warn( |
251
|
|
|
|
|
|
|
"Task dependencies are not calculated until the end of submission ... please to do not exit unless you are sure!" |
252
|
|
|
|
|
|
|
); |
253
|
0
|
|
|
|
|
|
$self->jobs->{ $self->current_job }->submission_failure(1); |
254
|
|
|
|
|
|
|
} |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
1; |