$pattern = '\-(9805558)\-(\d+)\.(out)'; # Make sure to change 9805558 to make your job id. $countFile = 'count.data'; # task count on nodes by seconds $usageFile = 'usage.data'; # accumulate user time on all nodes by seconds $nodeUsageFile = "nodeusage.data"; #detail of node usage by seconds $nodeUsageFiles = "%s_usage.data"; # %s -> host @varNames = qw/sd dim maxe/; # used for columns in resultfile $resultFile = "result%s.data"; # %s -> project id &scandir("."); @node = sort keys %hostCount; foreach $jobid (keys %startTime) { my $file = sprintf "wiki%s.txt", $jobid; open(WIKI, ">$file"); print WIKI `date -d \@$startTime{$jobid} +\"SGE array job started %c\n"`; print WIKI "Used a total of $userTotal{$jobid} CPU seconds "; print WIKI "over ",$stopTime{$jobid}-$startTime{$jobid}," seconds of elapsed time "; print WIKI "on ",0+@node," nodes\n"; $baseTime = $startTime{$jobid} if (!defined $baseTime or $startTime{$jobid} < $baseTime); $avgMaxEig=0; $count=0; if ($resultFile) { my $file = sprintf $resultFile, $jobid; open(DATA, ">$file"); print DATA "@varNames\n"; foreach $task (sort { $a <=> $b } keys %{$result{$jobid}}) { my %var = split($;,$result{$jobid}{$task}); print DATA "@var{@varNames}\n"; $avgMaxEig += $var{'maxe'}; $count += 1; } close(DATA); print 'avgMaxEig = ', $avgMaxEig/$count, "\n"; } printf WIKI "^ %18s ^^ %30s ^^^ %12s ^\n","Node ","Real Clock Time ","Ratio "; printf WIKI "^ %8s ^ %8s ^ %9s ^ %9s ^ %9s ^ %12s ^\n","Name ","Count ","Min ","Max ","Average ","User/Real "; foreach (@node) { if ( $hostCountByJob{$jobid}{$_} > 0) { printf WIKI "|%8s|%8d| %9.2f|%9.2f|%9.2f |%12.5f|\n", $_, $hostCountByJob{$jobid}{$_}, $hostRealMin{$jobid}{$_},$hostRealMax{$jobid}{$_}, $hostReal{$jobid}{$_}/$hostCountByJob{$jobid}{$_}, $hostUser{$jobid}{$_}/$hostReal{$jobid}{$_}; } } close(WIKI); } if ($countFile and open(DATA,">$countFile")) { my(@col,%byNode,$time,$count); $col[$_] = 0 for $[ .. $#node; foreach $time (sort { $a <=> $b } keys %timeCount) { printf DATA "%d %s\n", $time-$baseTime, "@col"; $byNode{$_} += $timeCount{$time}{$_} foreach keys %{$timeCount{$time}}; $count=0; $col[$_] = $count += $byNode{$node[$_]} for $[ .. $#node; printf DATA "%d %s\n", $time-$baseTime, "@col"; } close(DATA); } if ($usageFile and open(DATA,">$usageFile")) { my ($time, $lastTime, $slope, $usage); foreach $time (sort { $a <=> $b } keys %timeRate) { $usage += $slope*($time - $lastTime); $slope += $timeRate{$time}{$_} foreach keys %{$timeRate{$time}}; printf DATA "%d %.4f %.4f\n", $time-$baseTime, $slope, $usage; $lastTime = $time; } close(DATA); } if ($countFile and $usageFile) { foreach $jobid (keys %startTime) { my $plotTitle = 'Number of tasks on %s by time (seconds)'; # %s -> nodes my(@plot); $plot[$_] = "\"$countFile\" u 1:".(2+$_-$[)." t \"$node[$_]\" w filledcurves" for $[ .. $#node; my $plotTop = join(",",reverse @plot); my $titleTop = sprintf $plotTitle, 0+@node." nodes"; my $key = "off"; my ($t1,$t2) = (30*int(($startTime{$jobid}-$baseTime)/30),30*int(2+($stopTime{$jobid}-$baseTime)/30)); $titleTop = sprintf $plotTitle, "nodes @node" if $#node < 5; $key = "out horiz top right" if $#node < 9; open (PLOT, "| gnuplot" ); print PLOT <<"EOP"; set term pngcairo font "sans,10" size 640,640 set output "wiki$jobid.png" set multiplot layout 2,1 set xrange [$t1:$t2] set key $key set ylabel "Number of Tasks on node" plot $plotTop set key out horiz top right set ylabel "Total CPU usage" set xlabel "Time (seconds)" plot "$usageFile" u 1:3 w lines t "CPU seconds" EOP } } sub scanfile { my($file) = @_; my($jobid,$taskid) = ($file =~ /$pattern/); my($host,$start,$finish,$usr1,$usr2,$real,$user,$sys,$lhs,%var); open(FILE,$file) || next; local $/ = undef; #Read file as one string while () { study; /^Host (\S+)/m and $host=$1; /^Start (\d+)/m and $start=$1; /^Finish (\d+)/m and $finish=$1; /^SIGUSR1 (\d+)/m and $usr1=$1; /^SIGUSR2 (\d+)/m and $usr2=$1; /^real(.*?)m(.*?)s/m and $real=60*$1+$2; /^user(.*?)m(.*?)s/m and $user=60*$1+$2; /^sys(.*?)m(.*?)s/m and $sys=60*$1+$2; while(/(\S+)\s*=\s*(.*)/g) { $var{$1}=$2 }; } close(FILE); $result{$jobid}{$taskid} = join($;,%var); $SGEfile{$file} = sprintf "| %s | %.2f %8.2f %8.2f |", $host, $real, $user, $sys; $SGEfile{$file} .= sprintf " %d %d |", $usr1, $usr2; $SGEfile{$file} .= join(',', map {" $_=$var{$_}"} keys %var ); $finish = $usr2 if( $finish==0 ); $finish = $usr1 if( $finish==0 ); $finish > 0 || next; $real = $finish-$start if($real==0); $user = $real-$sys if($user==0); $startTime{$jobid} = $start if (!defined $startTime{$jobid} or $start < $startTime{$jobid}); $stopTime{$jobid} = $finish if (!defined $stopTime{$jobid} or $finish > $stopTime{$jobid}); $userTotal{$jobid} += $user; $hostCount{$host} += 1; $hostCountByJob{$jobid}{$host} += 1; $hostReal{$jobid}{$host} += $real; $hostRealMax{$jobid}{$host} = $real if (!defined $hostRealMax{$jobid}{$host} or $real > $hostRealMax{$jobid}{$host}); $hostRealMin{$jobid}{$host} = $real if (!defined $hostRealMin{$jobid}{$host} or $real < $hostRealMin{$jobid}{$host}); $hostUser{$jobid}{$host} += $user; $timeCount{$start}{$host} += 1; $timeCount{$finish}{$host} -= 1; $timeRate{$start}{$host} += $user/($finish-$start); $timeRate{$finish}{$host} -= $user/($finish-$start); } sub scandir { my($basedir) = @_; my(@file,@dir); opendir(DIR, $basedir) || return; foreach ( grep (/^[^\.]/,readdir(DIR)) ) { # ignore hidden files next if -l "$basedir/$_" ; # skip sym links push @file,$_ if /$pattern/; # save files with this pattern push @dir,$_ if -d "$basedir/$_" ; # save directories for recursion } closedir(DIR); foreach (@file) { &scanfile("$basedir/$_"); } foreach (@dir) { &scandir("$basedir/$_"); } }