File Coverage

blib/lib/HPC/Runner/Command/submit_jobs/Utils/Scheduler/Submit.pm
Criterion Covered Total %
statement 18 110 16.3
branch 0 36 0.0
condition 0 3 0.0
subroutine 6 13 46.1
pod 4 6 66.6
total 28 168 16.6


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;