File Coverage

blib/lib/HPC/Runner/MCE.pm
Criterion Covered Total %
statement 15 71 21.1
branch 0 18 0.0
condition n/a
subroutine 5 8 62.5
pod 2 3 66.6
total 22 100 22.0


line stmt bran cond sub pod time code
1             #!/usr/bin/env perl
2              
3             package HPC::Runner::MCE;
4              
5 1     1   22276 use MCE;
  1         1088850  
  1         6  
6 1     1   16574 use MCE::Queue;
  1         11807  
  1         6  
7 1     1   2187 use DateTime;
  1         122460  
  1         30  
8 1     1   972 use DateTime::Format::Duration;
  1         6250  
  1         48  
9              
10 1     1   902 use Moose;
  1         2794831  
  1         9  
11             extends 'HPC::Runner';
12             with 'MooseX::Getopt::Usage';
13              
14             =head1 NAME
15              
16             HPC::Runner::MCE - Job submission using MCE
17              
18             =head1 VERSION
19              
20             Version 0.01
21              
22             =cut
23              
24             our $VERSION = '2.39';
25              
26             =head1 SYNOPSIS
27              
28             Use MCE and MCE::Queue to run arbitrary bash commands in parallel using processes.
29              
30             =cut
31              
32             =head1 Variables
33              
34             =cut
35              
36             has 'queue' => (
37             traits => ['NoGetopt'],
38             is => 'rw',
39             lazy => 0, ## must be 0 to ensure the queue is created prior to spawning
40             default => sub {
41             my $self = shift;
42             return MCE::Queue->new();
43             }
44             );
45              
46             has 'mce' => (
47             traits => ['NoGetopt'],
48             is => 'rw',
49             lazy => 1,
50             default => sub {
51             my $self = shift;
52             return MCE->new(
53             max_workers => $self->procs, use_threads => 0, user_func => sub {
54             my $mce = shift;
55             while (1) {
56             my ($counter, $cmd) = $self->queue->dequeue(2);
57             last unless defined $counter;
58             $self->counter($counter);
59             $self->cmd($cmd);
60             $self->run_command_mce();
61             }
62             }
63             );
64             }
65             );
66              
67             has 'using_mce' => (
68             is => 'rw',
69             isa => 'Bool',
70             default => 1,
71             required => 1,
72             );
73              
74              
75             =head1 SUBROUTINES/METHODS
76              
77             =cut
78              
79             =head2 go
80              
81             Initialize MCE things and use Runner::Init to parse and exec commands
82              
83             =cut
84              
85             sub go{
86 0     0 1   my $self = shift;
87              
88 0           my $dt1 = DateTime->now();
89              
90 0           $self->prepend_logfile("MAIN_");
91 0           $self->log($self->init_log);
92 0           $self->mce->spawn;
93              
94             #MCE specific
95 0           $self->parse_file_mce;
96              
97 0           $DB::single=2;
98             # MCE workers dequeue 2 elements at a time. Thus the reason for * 2.
99 0           $self->queue->enqueue((undef) x ($self->procs * 2));
100             # MCE will automatically shutdown after running for 1 or no args.
101 0           $self->mce->run(1);
102             #End MCE specific
103              
104 0           my $dt2 = DateTime->now();
105 0           my $duration = $dt2 - $dt1;
106 0           my $format = DateTime::Format::Duration->new(
107             pattern => '%Y years, %m months, %e days, %H hours, %M minutes, %S seconds'
108             );
109              
110 0           $self->log->info("Total execution time ".$format->format_duration($duration));
111 0           return;
112             }
113              
114             =head2 parse_file_mce
115              
116             The default method of parsing the file.
117              
118             #starts a comment
119             wait - says wait until all other processes/threads exitcode
120              
121             #this is a one line command
122             echo "starting"
123              
124             #This is a multiline command
125             echo "starting line 1" \
126             echo "starting line 2" \
127             echo "finishing
128              
129             =cut
130              
131             sub parse_file_mce{
132 0     0 1   my $self = shift;
133              
134 0           $DB::single=2;
135              
136 0 0         my $fh = IO::File->new( $self->infile, q{<} ) or $self->log->fatal("Error opening file ".$self->infile." ".$!);
137 0 0         die unless $fh;
138              
139 0           while(<$fh>){
140 0           my $line = $_;
141 0 0         next unless $line;
142 0 0         next unless $line =~ m/\S/;
143 0           $self->process_lines($line);
144 0           $self->wait(0);
145             }
146              
147 0           $DB::single=2;
148             }
149              
150             sub process_lines{
151 0     0 0   my $self = shift;
152 0           my $line = shift;
153              
154 0 0         return if $line =~ m/^#/;
155 0 0         if($self->has_cmd){
156 0           $DB::single=2;
157 0           $self->add_cmd($line);
158 0 0         if($line =~ m/\\$/){
159 0           return;
160             }
161             else{
162 0           $self->log->info("Enqueuing command:\n".$self->cmd);
163             #MCE
164 0           $self->queue->enqueue($self->counter, $self->cmd);
165             #Threads
166             # $self->run_command_threads;
167 0           $self->clear_cmd;
168 0           $self->inc_counter;
169             }
170             }
171             else{
172 0           $DB::single=2;
173 0           $self->cmd($line);
174 0 0         if($line =~ m/\\$/){
    0          
175 0           next;
176             }
177             elsif( $self->match_cmd(qr/^wait$/) ){
178 0           $DB::single=2;
179 0           $self->log->info("Beginning command:\n".$self->cmd);
180 0           $self->log->info("Waiting for all children to complete...");
181 0           $self->clear_cmd;
182             #MCE
183              
184 0           $self->wait(1);
185 0           push(@{$self->jobref}, []);
  0            
186 0           $self->queue->enqueue((undef) x ($self->procs * 2));
187 0           $self->mce->run(0); # 0 indicates do not shutdown after running
188              
189             # #THREADS
190             # $self->threads->wait_all_children;
191 0           $self->log->info("All children have completed processing!");
192             }
193             else{
194 0           $self->log->info("Enqueuing command:\n".$self->cmd);
195 0           $DB::single=2;
196             #MCE
197 0           $self->queue->enqueue($self->counter, $self->cmd);
198             # #Threads
199             # $self->run_command_threads;
200 0           $self->clear_cmd;
201 0           $self->inc_counter;
202             }
203             }
204             }
205              
206             #use namespace::autoclean;
207             1;
208              
209             =head1 AUTHOR
210              
211             Jillian Rowe, C<< <jillian.e.rowe at gmail.com> >>
212             Mario Roy, C<< <marioeroy at gmail.com> >>
213              
214             =head1 BUGS
215              
216             Please report any bugs or feature requests to C<bug-runner-init at rt.cpan.org>, or through
217             the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=HPC::Runner::MCE>. I will be notified, and then you'll
218             automatically be notified of progress on your bug as I make changes.
219              
220              
221             =head1 SUPPORT
222              
223             You can find documentation for this module with the perldoc command.
224              
225             perldoc HPC::Runner::MCE
226              
227              
228             You can also look for information at:
229              
230             =over 4
231              
232             =item * RT: CPAN's request tracker (report bugs here)
233              
234             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=HPC-Runner-MCE>
235              
236             =item * AnnoCPAN: Annotated CPAN documentation
237              
238             L<http://annocpan.org/dist/HPC-Runner-MCE>
239              
240             =item * CPAN Ratings
241              
242             L<http://cpanratings.perl.org/d/HPC-Runner-MCE>
243              
244             =item * Search CPAN
245              
246             L<http://search.cpan.org/dist/HPC-Runner-MCE/>
247              
248             =back
249              
250             =head1 Acknowledgements
251              
252             This module was originally developed at and for Weill Cornell Medical
253             College in Qatar within ITS Advanced Computing Team. With approval from
254             WCMC-Q, this information was generalized and put on github, for which
255             the authors would like to express their gratitude.
256              
257             =head1 LICENSE AND COPYRIGHT
258              
259             Copyright 2014 Weill Cornell Medical College.
260              
261             This program is free software; you can redistribute it and/or modify it
262             under the terms of the the Artistic License (2.0). You may obtain a
263             copy of the full license at:
264              
265             L<http://www.perlfoundation.org/artistic_license_2_0>
266              
267             Any use, modification, and distribution of the Standard or Modified
268             Versions is governed by this Artistic License. By using, modifying or
269             distributing the Package, you accept this license. Do not use, modify,
270             or distribute the Package, if you do not accept this license.
271              
272             If your Modified Version has been derived from a Modified Version made
273             by someone other than you, you are nevertheless required to ensure that
274             your Modified Version complies with the requirements of this license.
275              
276             This license does not grant you the right to use any trademark, service
277             mark, tradename, or logo of the Copyright Holder.
278              
279             This license includes the non-exclusive, worldwide, free-of-charge
280             patent license to make, have made, use, offer to sell, sell, import and
281             otherwise transfer the Package with respect to any patent claims
282             licensable by the Copyright Holder that are necessarily infringed by the
283             Package. If you institute patent litigation (including a cross-claim or
284             counterclaim) against any party alleging that the Package constitutes
285             direct or contributory patent infringement, then this Artistic License
286             to you shall terminate on the date that such litigation is filed.
287              
288             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
289             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
290             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
291             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
292             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
293             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
294             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
295             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
296              
297              
298             =cut
299              
300             # End of Runner::MCE
301