Changeset 27643
- Timestamp:
- 2013-06-18T10:30:13+12:00 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
gs2-extensions/parallel-building/trunk/src/bin/script/generate_gantt.pl
r27590 r27643 1 1 #!/usr/bin/perl 2 2 3 # Pragma 3 4 use strict; 4 5 use warnings; 5 6 use 5.012; # so readdir assigns to $_ in a lone while test 7 8 # Modules 6 9 use Sort::Naturally; 7 10 use POSIX qw(floor strftime); … … 9 12 print "\n===== Generate Timing (GANTT) =====\n"; 10 13 11 # 0. Configuration 14 # 0. Init 15 # - configurables 16 my $chart_width = 1600; 12 17 my $debug = 0; 13 my $import_dir; 14 15 # 1. Initialization 16 if (!defined $ARGV[0] || !-d $ARGV[0]) 17 { 18 &printUsage('Directory not provided or doesn\'t exist'); 19 } 20 my $dir = $ARGV[0]; 21 my $timing_csv_path = &filenameCat($dir, 'timing.csv'); 22 if (!-e $timing_csv_path) 23 { 24 &printUsage('Directory doesn\'t contain timing.csv: ' . $dir); 25 } 26 print 'Timing File: ' . $timing_csv_path . "\n"; 27 my $chart_width = 1024; 28 if (defined $ARGV[1]) 29 { 30 if ($ARGV[1] !~ /^\d+$/) 31 { 32 &printUsage('Chart width not a number'); 33 } 34 $chart_width = $ARGV[1]; 18 # - globals 19 my $chart_count = 0; 20 my @months = ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"); 21 22 # 1. Parse options 23 while (defined $ARGV[0] && $ARGV[0] =~ /^-/) 24 { 25 my $option = shift(@ARGV); 26 if ($option eq '-debug') 27 { 28 $debug = 1; 29 } 30 elsif ($option eq '-width') 31 { 32 if (!defined $ARGV[0]) 33 { 34 &printUsage('Error! No width value specified'); 35 } 36 my $value = shift(@ARGV); 37 if ($value !~ /^\d+$/) 38 { 39 &printUsage('Error! Chart width not a number'); 40 } 41 $chart_width = $value; 42 } 43 else 44 { 45 &printUsage('Error! Unknown option: ' . $option); 46 } 35 47 } 36 48 print "Chart Width: " . $chart_width . "px\n"; 37 38 my ($epoc) = $dir =~ /(\d+)$/; 39 my $gantt_path = $dir . '/' . $epoc . '-gantt.html'; 40 print "Gantt Chart: " . $gantt_path . "\n"; 41 49 print "Debug? " . ($debug ? 'Yes' : 'No') . "\n"; 42 50 print "===================================\n\n"; 43 51 44 # Read in timing.csv and parse information into data structure 45 my $timing_data = {}; 46 my $id_2_worker_id = {}; 47 if (open(TIN, '<:utf8', $timing_csv_path)) 48 { 49 my $line; 50 while ($line = <TIN>) 51 { 52 my @parts = split(/,/, $line); 53 if ($parts[1] eq 'M0') 54 { 55 $timing_data->{'M'} = {'N'=>$parts[2], 'S'=>$parts[3], 'E'=>$parts[4]}; 56 } 57 elsif ($parts[1] =~ /W\d+/) 58 { 59 $timing_data->{$parts[1]} = {'N'=>$parts[2], 'S'=>$parts[3], 'E'=>$parts[4], 'F'=>{}}; 60 $id_2_worker_id->{$parts[0]} = $parts[1]; 61 } 62 elsif ($parts[1] =~ /T\d+/) 63 { 64 my $worker_id = $id_2_worker_id->{$parts[7]}; 65 my $stop = $parts[4]; 66 my $filepath = $parts[8]; 67 $filepath =~ s/^\s+|\s+$//g; 68 $import_dir = &longestCommonPath($filepath, $import_dir); 69 $timing_data->{$worker_id}->{'F'}->{$parts[3]} = {'FN'=>$filepath, 'PS'=>($stop - $parts[5]), 'PE'=>$stop, 'E'=>$stop, 'DL'=>$parts[6]}; 70 } 71 } 72 close(TIN); 73 } 74 else 75 { 76 die('Error! Failed to open file for reading: ' . $timing_csv_path); 77 } 78 my $number_of_workers = scalar(keys(%{$id_2_worker_id}));; 79 80 # 3. Produce pretty HTML chart of timing information including jobs 81 print " * Generating timing information as HTML... "; 82 open(HTMLOUT, '>:utf8', $gantt_path) or die('Error! Failed to open file for writing: gantt.html'); 83 print HTMLOUT "<html>\n"; 84 print HTMLOUT '<head>' . "\n"; 85 print HTMLOUT '<style type="text/css">' . "\n"; 86 print HTMLOUT 'div.thread {position:relative}' . "\n"; 87 print HTMLOUT 'div.master {border:1px solid gray;color:white;font-weight:bold}' . "\n"; 88 print HTMLOUT 'div.worker {border:1px solid black;background-color:green;color:white;font-weight:bold}' . "\n"; 89 print HTMLOUT 'div.time {font-size:smaller;font-weight:normal}' . "\n"; 90 print HTMLOUT 'div.job {background-color:transparent;color:black;border:1px solid black;display:block;font-size:smaller;position:relative;text-align:center;overflow:hidden}' . "\n"; 91 print HTMLOUT 'span.process {z-index:-1;background-color:#C7C7C7;position:absolute}' . "\n"; 92 print HTMLOUT 'span.label {z-index:1;background-color:transparent;overflow:hidden;white-space:nowrap;}' . "\n"; 93 print HTMLOUT "th {text-align:left}\n"; 94 print HTMLOUT '</style>' . "\n"; 95 print HTMLOUT '</head>' . "\n"; 96 print HTMLOUT "<body>\n"; 97 print HTMLOUT "<h2>Statistics</h2>\n"; 98 print HTMLOUT "<table>\n"; 99 100 my $total_duration = $timing_data->{'M'}->{'E'} - $timing_data->{'M'}->{'S'}; 101 my $file_count = 0; 102 my $data_locality = 0; 103 my $total_io_time = 0; 104 my $total_process_time = 0; 105 my $fastest_file = 0; 106 my $slowest_file = 0; 107 my $problem_files = 0; 108 foreach my $worker_id (keys %{$timing_data}) 109 { 110 if ($worker_id ne 'M') 111 { 112 foreach my $job_start ( keys %{$timing_data->{$worker_id}->{'F'}} ) 113 { 114 my $process_start = $timing_data->{$worker_id}->{'F'}->{$job_start}->{'PS'}; 115 my $process_end = $timing_data->{$worker_id}->{'F'}->{$job_start}->{'PE'}; 116 my $job_end = $timing_data->{$worker_id}->{'F'}->{$job_start}->{'E'}; 117 if ($process_start == 0 || $process_end == 0 || $job_end == 0) 118 { 119 $problem_files++; 120 } 121 else 122 { 123 my $io_duration = ($process_start - $job_start) + ($job_end - $process_end); 124 my $process_duration = $process_end - $process_start; 125 my $total_duration = $io_duration + $process_duration; 126 &debugPrint("filename: " . $timing_data->{$worker_id}->{'F'}->{$job_start}->{'FN'}); 127 &debugPrint("start: $job_start ps: $process_start pe: $process_end end: $job_end"); 128 &debugPrint("io: $io_duration process: $process_duration duration: $total_duration"); 129 # Running stats 130 $total_io_time += $io_duration; 131 $total_process_time += $process_duration; 132 if ($fastest_file == 0 || $total_duration < $fastest_file) 52 # 2. Search for valid directories (containing timing.csv) 53 while (defined $ARGV[0]) 54 { 55 my $dir = shift(@ARGV); 56 if (!-d $dir) 57 { 58 &printUsage('Error! Not a directory: ' . $dir); 59 } 60 &searchForTimingCSV($dir); 61 } 62 63 # 3. Done 64 print "Complete!\n\n"; 65 print "===================================\n"; 66 print 'Generated ' . $chart_count . " charts\n"; 67 print "===================================\n\n"; 68 exit; 69 ## main() ## 70 71 72 ## @function searchForTimingCSV() 73 # 74 sub searchForTimingCSV 75 { 76 my $dir = shift(@_); 77 # For every directory where we find a timing.csv we generate a gantt chart 78 my $timing_path = &filenameCat($dir, 'timing.csv'); 79 if (-e $timing_path) 80 { 81 &generateChart($dir, $timing_path); 82 } 83 # We also recursively search for other directories containing timing.csv's 84 opendir(my $dh, $dir) or &printError('Failed to open directory for reading: ' . $dir); 85 while (readdir($dh)) 86 { 87 my $file = $_; 88 if ($file !~ /^\./) 89 { 90 my $path = &filenameCat($dir, $file); 91 if (-d $path) 92 { 93 &searchForTimingCSV($path); 94 } 95 } 96 } 97 } 98 ## searchForTimingCSV() ## 99 100 101 ## @function generateChart() 102 # 103 sub generateChart 104 { 105 my $dir = shift(@_); 106 my $timing_csv_path = shift(@_); 107 my $import_dir; 108 my ($epoc) = $dir =~ /(\d+)$/; 109 my $gantt_path = $dir . '/' . $epoc . '-gantt.html'; 110 111 print ' * Generating chart for: ' . $dir . "\n"; 112 print ' - timing file: ' . $timing_csv_path . "\n"; 113 print ' - gantt chart: ' . $gantt_path . "\n"; 114 115 # Read in timing.csv and parse information into data structure 116 print ' - parsing timing.csv... '; 117 my $timing_data = {}; 118 my $id_2_worker_id = {}; 119 if (open(TIN, '<:utf8', $timing_csv_path)) 120 { 121 my $line; 122 while ($line = <TIN>) 123 { 124 my @parts = split(/,/, $line); 125 if ($parts[1] eq 'M0') 126 { 127 $timing_data->{'M'} = {'N'=>$parts[2], 'S'=>$parts[3], 'E'=>$parts[4]}; 128 } 129 elsif ($parts[1] =~ /W\d+/) 130 { 131 $timing_data->{$parts[1]} = {'N'=>$parts[2], 'S'=>$parts[3], 'E'=>$parts[4], 'F'=>{}}; 132 $id_2_worker_id->{$parts[0]} = $parts[1]; 133 } 134 elsif ($parts[1] =~ /T\d+/) 135 { 136 my $worker_id = $id_2_worker_id->{$parts[7]}; 137 my $stop = $parts[4]; 138 my $filepath = $parts[8]; 139 $filepath =~ s/^\s+|\s+$//g; 140 $import_dir = &longestCommonPath($filepath, $import_dir); 141 $timing_data->{$worker_id}->{'F'}->{$parts[3]} = {'FN'=>$filepath, 'S'=>$parts[3], 'PS'=>($stop - $parts[5]), 'PE'=>$stop, 'E'=>$stop, 'DL'=>$parts[6]}; 142 } 143 } 144 close(TIN); 145 } 146 else 147 { 148 die('Error! Failed to open file for reading: ' . $timing_csv_path); 149 } 150 my $number_of_workers = scalar(keys(%{$id_2_worker_id}));; 151 print "Done\n"; 152 153 # 3. Produce pretty HTML chart of timing information including jobs 154 print " - generating timing information as chart in HTML... "; 155 open(HTMLOUT, '>:utf8', $gantt_path) or die('Error! Failed to open file for writing: gantt.html'); 156 print HTMLOUT "<html>\n"; 157 print HTMLOUT '<head>' . "\n"; 158 print HTMLOUT '<style type="text/css">' . "\n"; 159 print HTMLOUT 'div.thread {position:relative}' . "\n"; 160 print HTMLOUT 'div.master {border:1px solid gray;color:white;font-weight:bold}' . "\n"; 161 print HTMLOUT 'div.worker {border:1px solid black;background-color:green;color:white;font-weight:bold}' . "\n"; 162 print HTMLOUT 'div.time {font-size:smaller;font-weight:normal}' . "\n"; 163 print HTMLOUT 'div.job {background-color:transparent;color:black;border:1px solid black;display:block;font-size:smaller;position:relative;text-align:center;overflow:hidden}' . "\n"; 164 print HTMLOUT 'span.process {z-index:-1;background-color:#C7C7C7;position:absolute}' . "\n"; 165 print HTMLOUT 'span.label {z-index:1;background-color:transparent;overflow:hidden;white-space:nowrap;}' . "\n"; 166 print HTMLOUT "th {text-align:left}\n"; 167 print HTMLOUT '</style>' . "\n"; 168 print HTMLOUT '</head>' . "\n"; 169 print HTMLOUT "<body>\n"; 170 print HTMLOUT "<h2>Statistics</h2>\n"; 171 print HTMLOUT "<table>\n"; 172 173 my $total_duration = $timing_data->{'M'}->{'E'} - $timing_data->{'M'}->{'S'}; 174 my $file_count = 0; 175 my $data_locality = 0; 176 my $total_io_time = 0; 177 my $total_process_time = 0; 178 my $fastest_file = 0; 179 my $slowest_file = 0; 180 my $problem_files = 0; 181 foreach my $worker_id (keys %{$timing_data}) 182 { 183 if ($worker_id ne 'M') 184 { 185 foreach my $job_start ( keys %{$timing_data->{$worker_id}->{'F'}} ) 186 { 187 my $process_start = $timing_data->{$worker_id}->{'F'}->{$job_start}->{'PS'}; 188 my $process_end = $timing_data->{$worker_id}->{'F'}->{$job_start}->{'PE'}; 189 my $job_end = $timing_data->{$worker_id}->{'F'}->{$job_start}->{'E'}; 190 if ($process_start == 0 || $process_end == 0 || $job_end == 0) 133 191 { 134 $ fastest_file = $total_duration;192 $problem_files++; 135 193 } 136 if ($slowest_file == 0 || $total_duration > $slowest_file)194 else 137 195 { 138 $slowest_file = $total_duration; 196 my $io_duration = ($process_start - $job_start) + ($job_end - $process_end); 197 my $process_duration = $process_end - $process_start; 198 my $total_duration = $io_duration + $process_duration; 199 &debugPrint("filename: " . $timing_data->{$worker_id}->{'F'}->{$job_start}->{'FN'}); 200 &debugPrint("start: $job_start ps: $process_start pe: $process_end end: $job_end"); 201 &debugPrint("io: $io_duration process: $process_duration duration: $total_duration"); 202 # Running stats 203 $total_io_time += $io_duration; 204 $total_process_time += $process_duration; 205 if ($fastest_file == 0 || $total_duration < $fastest_file) 206 { 207 $fastest_file = $total_duration; 208 } 209 if ($slowest_file == 0 || $total_duration > $slowest_file) 210 { 211 $slowest_file = $total_duration; 212 } 139 213 } 140 } 141 # Shorten filename 142 if (defined $timing_data->{$worker_id}->{'F'}->{$job_start}->{'FN'}) 143 { 144 $timing_data->{$worker_id}->{'F'}->{$job_start}->{'FN'} = substr($timing_data->{$worker_id}->{'F'}->{$job_start}->{'FN'}, length($import_dir) + 1); 145 } 146 $file_count++; 147 if ($timing_data->{$worker_id}->{'F'}->{$job_start}->{'DL'} == 1) 148 { 149 $data_locality++; 150 } 151 } 152 } 153 } 154 my $avg_processing_time = floor(($total_io_time + $total_process_time) / $file_count); 155 my @months = ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"); 156 157 print HTMLOUT "<tr><th>Import Directory:</th><td>" . $import_dir . "</td></tr>\n"; 158 my ($sec, $min, $hour, $day, $month, $year) = (localtime($timing_data->{'M'}->{'S'}))[0,1,2,3,4,5]; 159 print HTMLOUT "<tr><th>Start Time:</th><td>" . sprintf('%04d%s%02d %02d:%02d:%02d', ($year+1900), $months[$month], $day, $hour, $min, $sec) . "</td></tr>\n"; 160 print HTMLOUT "<tr><th>Processing Time:</th><td>" . &renderTime($total_duration) . "</td></tr>\n"; 161 print HTMLOUT "<tr><th>Processing Threads:</th><td>" . $number_of_workers . "</td></tr>\n"; 162 print HTMLOUT "<tr><th>Files Processed:</th><td>" . $file_count . "</td></tr>\n"; 163 if ($data_locality > 0) 164 { 165 print HTMLOUT "<tr><th>Data Locality:</th><td>" . sprintf('%d%% [%d out of %d]', (($data_locality / $file_count) * 100), $data_locality, $file_count) . "</td></tr>\n"; 166 } 167 print HTMLOUT "<tr><th>Serial Processing Time:</th><td>" . &renderTime($total_process_time) . "</td></tr>\n"; 168 print HTMLOUT "<tr><th>Serial IO Time:</th><td>" . &renderTime($total_io_time) . "</td></tr>\n"; 169 print HTMLOUT "<tr><th>Average File Processing Time:</th><td>" . &renderTime($avg_processing_time) . "</td></tr>\n"; 170 print HTMLOUT "<tr><th>Fastest File:</th><td>" . &renderTime($fastest_file) . "</td></tr>\n"; 171 print HTMLOUT "<tr><th>Slowest File:</th><td>" . &renderTime($slowest_file) . "</td></tr>\n"; 172 print HTMLOUT "<tr><th>Problem Files:</th><td>" . $problem_files . "</td></tr>\n"; 173 174 print HTMLOUT "</table>\n"; 175 print HTMLOUT "<hr />\n"; 176 print HTMLOUT "<h2>Timing Chart (Gannt)</h2>\n"; 177 print HTMLOUT renderLine($chart_width, $timing_data->{'M'}->{'S'}, $timing_data->{'M'}->{'E'}, 'master', $timing_data->{'M'}->{'N'}, $timing_data->{'M'}->{'S'}, $timing_data->{'M'}->{'E'}, {}); 178 foreach my $worker_id (nsort keys %{$timing_data}) 179 { 180 if ($worker_id ne 'M') 181 { 182 my $data = $timing_data->{$worker_id}; 183 print HTMLOUT renderLine($chart_width, $timing_data->{'M'}->{'S'}, $timing_data->{'M'}->{'E'}, 'worker', $worker_id . ' [' . $data->{'N'} . ']', $data->{'S'}, $data->{'E'}, $data->{'F'}); 184 } 185 } 186 print HTMLOUT '<div>' . "\n"; 187 print HTMLOUT "</body>\n"; 188 print HTMLOUT "</html>"; 189 close(HTMLOUT); 190 191 print "Done!\n"; 192 print "Complete!\n\n"; 193 exit; 214 # Shorten filename 215 if (defined $timing_data->{$worker_id}->{'F'}->{$job_start}->{'FN'}) 216 { 217 $timing_data->{$worker_id}->{'F'}->{$job_start}->{'FN'} = substr($timing_data->{$worker_id}->{'F'}->{$job_start}->{'FN'}, length($import_dir) + 1); 218 } 219 $file_count++; 220 if ($timing_data->{$worker_id}->{'F'}->{$job_start}->{'DL'} == 1) 221 { 222 $data_locality++; 223 } 224 } 225 } 226 } 227 my $avg_processing_time = floor(($total_io_time + $total_process_time) / $file_count); 228 my $avg_io_time = int(($total_io_time / $file_count) + 0.5); 229 my $avg_cpu_time = int(($total_process_time / $file_count) + 0.5); 230 231 print HTMLOUT "<tr><th>Import Directory:</th><td>" . $import_dir . "</td></tr>\n"; 232 my ($sec, $min, $hour, $day, $month, $year) = (localtime($timing_data->{'M'}->{'S'}))[0,1,2,3,4,5]; 233 print HTMLOUT "<tr><th>Start Time:</th><td>" . sprintf('%04d%s%02d %02d:%02d:%02d', ($year+1900), $months[$month], $day, $hour, $min, $sec) . "</td></tr>\n"; 234 print HTMLOUT "<tr><th>Processing Time:</th><td>" . &renderTime($total_duration) . "</td></tr>\n"; 235 print HTMLOUT "<tr><th>Processing Threads:</th><td>" . $number_of_workers . "</td></tr>\n"; 236 print HTMLOUT "<tr><th>Files Processed:</th><td>" . $file_count . "</td></tr>\n"; 237 if ($data_locality > 0) 238 { 239 print HTMLOUT "<tr><th>Data Locality:</th><td>" . sprintf('%d%% [%d out of %d]', (($data_locality / $file_count) * 100), $data_locality, $file_count) . "</td></tr>\n"; 240 } 241 print HTMLOUT "<tr><th>Serial Processing Time:</th><td>" . &renderTime($total_process_time) . "</td></tr>\n"; 242 print HTMLOUT "<tr><th>Serial IO Time:</th><td>" . &renderTime($total_io_time) . "</td></tr>\n"; 243 print HTMLOUT '<tr><th>IO Percentage:</th><td>' . sprintf('%d%%', (($total_io_time / $total_process_time) * 100)) . "</td></tr>\n"; 244 print HTMLOUT "<tr><th>Average File Processing Time:</th><td>" . &renderTime($avg_processing_time) . "</td></tr>\n"; 245 print HTMLOUT "<tr><th>Average File IO Time:</th><td>" . &renderTime($avg_io_time) . "</td></tr>\n"; 246 print HTMLOUT "<tr><th>Average File CPU Time:</th><td>" . &renderTime($avg_cpu_time) . "</td></tr>\n"; 247 print HTMLOUT "<tr><th>Fastest File:</th><td>" . &renderTime($fastest_file) . "</td></tr>\n"; 248 print HTMLOUT "<tr><th>Slowest File:</th><td>" . &renderTime($slowest_file) . "</td></tr>\n"; 249 print HTMLOUT "<tr><th>Problem Files:</th><td>" . $problem_files . "</td></tr>\n"; 250 251 print HTMLOUT "</table>\n"; 252 print HTMLOUT "<hr />\n"; 253 print HTMLOUT "<h2>Timing Chart (Gannt)</h2>\n"; 254 print HTMLOUT renderLine($chart_width, $timing_data->{'M'}->{'S'}, $timing_data->{'M'}->{'E'}, 'master', $timing_data->{'M'}->{'N'}, $timing_data->{'M'}->{'S'}, $timing_data->{'M'}->{'E'}, {}); 255 foreach my $worker_id (nsort keys %{$timing_data}) 256 { 257 if ($worker_id ne 'M') 258 { 259 my $data = $timing_data->{$worker_id}; 260 print HTMLOUT renderLine($chart_width, $timing_data->{'M'}->{'S'}, $timing_data->{'M'}->{'E'}, 'worker', $worker_id . ' [' . $data->{'N'} . ']', $data->{'S'}, $data->{'E'}, $data->{'F'}); 261 } 262 } 263 print HTMLOUT '<div>' . "\n"; 264 print HTMLOUT "</body>\n"; 265 print HTMLOUT "</html>"; 266 close(HTMLOUT); 267 print "Done!\n\n"; 268 $chart_count++; 269 } 270 ## generateChart() ## 194 271 195 272 … … 213 290 my $path = join('/', @_); 214 291 $path =~ s/[\/\\]+/\//g; 215 # protocols216 $path =~ s/^(HDFS|HDFSShell|HDThriftFS):\//$1:\/\//;217 292 return $path; 218 293 } 219 294 ## filenameCat() ## 295 296 297 ## @function printError() 298 # 299 sub printError 300 { 301 my $msg = shift(@_); 302 die('Error! ' . $msg . "\n\n"); 303 } 304 ## printError() ## 305 220 306 221 307 ## @function printUsage() … … 228 314 print 'Error! ' . $msg . "\n"; 229 315 } 230 die("Usage: generate_gantt.pl <results dir> [<width in pixels>]\n\n");316 die("Usage: generate_gantt.pl [-width <width in pixels>] <dir> [<dir> ...]\n\n"); 231 317 } 232 318 ## printUsage() ## … … 241 327 if (defined $path_current) 242 328 { 329 # Hide protocol before we split by slash 330 $path_new =~ s/:\/\//:/; 331 $path_current =~ s/:\/\//:/; 243 332 my @path_new_parts = split(/\//, $path_new); 244 333 my @path_current_parts = split(/\//, $path_current); … … 256 345 } 257 346 $result = &filenameCat(@path_parts); 347 # Restore protocol 348 $result =~ s/:/:\/\//; 258 349 } 259 350 else … … 312 403 my $rjend = $jobs->{$jstart}->{'E'} - $start; 313 404 my $jduration = $jobs->{$jstart}->{'E'} - $jstart; 405 my $io_duration = $rpstart - $rjstart; 406 my $cpu_duration = $rpend - $rpstart; 314 407 # Scale Job co-ordinates 315 408 my $jleft_percent = $rjstart / $duration; … … 331 424 $html .= 'border:1px dashed black;'; 332 425 } 333 $html .= '" title="FN:' . $jobs->{$jstart}->{'FN'} . ', S:' . renderTime($rjstart) . ', E:' . renderTime($rjend) . ', CPU: ' . $cpu_percent . '%"><span class="process" style="left:' . $rpleft . 'px;width:' . $rpwidth . 'px"> </span><span class="label"';426 $html .= '" title="FN:' . $jobs->{$jstart}->{'FN'} . ', S:' . &renderTime($rjstart) . ', E:' . &renderTime($rjend) . ', CPU: ' . $cpu_percent . '% [' . &renderTime($io_duration) . ', ' . &renderTime($cpu_duration) . ']"><span class="process" style="left:' . $rpleft . 'px;width:' . $rpwidth . 'px"> </span><span class="label"'; 334 427 if ($jobs->{$jstart}->{'DL'} != 1) 335 428 { … … 365 458 $time_str = sprintf('%dh%02dm%02ds', $hours, $minutes, $seconds); 366 459 } 367 els if ($minutes > 0)460 else 368 461 { 369 462 $time_str = sprintf('%dm%02ds', $minutes, $seconds); 370 463 } 371 else372 {373 $time_str = $seconds . 's';374 }375 464 return $time_str; 376 465 }
Note:
See TracChangeset
for help on using the changeset viewer.