/[pdpsoft]/trunk/nl.nikhef.ndpf.tools/mpi/submit_filter/pbs/submit_filter.pl
ViewVC logotype

Contents of /trunk/nl.nikhef.ndpf.tools/mpi/submit_filter/pbs/submit_filter.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2226 - (show annotations) (download) (as text)
Mon Mar 7 11:44:15 2011 UTC (10 years, 10 months ago) by fbernabe
File MIME type: text/x-prolog
File size: 4077 byte(s)
The files for building submit_filter



1 #!/usr/bin/perl
2
3 # This script read a submission script on the standard input, modifies
4 # it, and writes the modified script on standard output. This script
5 # makes two modifications:
6 #
7 # * correct the node specification to allow all cpus to be used
8 # * add a users DN as the "account" field if available
9 #
10
11 my $GLOBUS_LOCATION = '/opt/globus';
12
13 while (<STDIN>) {
14
15 # By default just copy the line.
16 $line = $_;
17
18 # If there is a nodes line, then extract the value and adjust it
19 # as necessary. Only modify the simple nodes request. If there
20 # is a more complicated request assume that the user knows what
21 # he/she is doing and leave it alone.
22 if (m/#PBS\s+-l\s+nodes=(\d+)\s*$/) {
23 $line = process_nodes($1);
24 }
25
26 # If there is an existing accounts line, delete it.
27 if (m/#PBS\s+-A/) {
28 $line = '';
29 }
30
31 # Check to see if an X509 proxy variable is set.
32 if (m/#PBS\s+-v.*X509_USER_PROXY=([^,]+)/) {
33 my $output = `export LD_LIBRARY_PATH=$GLOBUS_LOCATION/lib; $GLOBUS_LOCATION/bin/grid-proxy-info -f $1 -subject 2>&1`;
34 chomp($output);
35 if ($output) {
36 $line = "#PBS -A '$output'\n$_";
37 }
38 }
39
40 print $line;
41 }
42
43 # This takes the number specified in the "nodes" specification and
44 # returns a "PBS -l" line which can be allocated on the available
45 # resources. This essentially does per-cpu allocation.
46 sub process_nodes {
47 my $nodes = shift;
48 my $line = "";
49
50 # Collect information from the pbsnodes command on the number of
51 # machine and cpus available. Don't do anything with offline
52 # nodes.
53 open PBS, "pbsnodes -a |";
54 my $state = 1;
55 my %machines;
56 while (<PBS>) {
57 if (m/state\s*=\s*(\w+)/) {
58 $state = ($1 eq "offline") ? 0 : 1;
59 } elsif (m/status\s*=\s*.*ncpus=(\d+),/) {
60 my $ncpus = $1;
61 if ($state) {
62 if (defined($machines{$ncpus})) {
63 $machines{$ncpus} = $machines{$ncpus}+1;
64 } else {
65 $machines{$ncpus} = 1;
66 }
67 }
68 }
69 }
70 close PBS;
71
72 # Count the total number of machines and cpus.
73 my $tnodes = 0;
74 my $tcpus = 0;
75 my $maxcpu = 0;
76 foreach my $ncpus (sort num_ascending keys %machines) {
77 $tnodes += $machines{$ncpus};
78 $tcpus += $machines{$ncpus}*$ncpus;
79 $maxcpu = $ncpus if ($tcpus>=$nodes);
80 }
81
82 if ($maxcpu==0) {
83
84 # There aren't enough cpus to handle the request. Just pass
85 # the request through and let the job fail.
86 $line .= "#PBS -l nodes=$nodes\n";
87
88 } else {
89
90 $line .="#PBS -l ";
91
92 # We've already identified the largest machine we'll have to
93 # allocate. Start by allocating one of those and iterate until
94 # all are used.
95 my %allocated;
96 my $remaining_cpus = $nodes;
97 my $remaining_nodes = $tnodes;
98 foreach my $ncpus (sort num_descending keys %machines) {
99 if ($ncpus<=$maxcpu && $remaining_cpus>0) {
100 my $nmach = $machines{$ncpus};
101 for (my $i=0;
102 ($i<$nmach) && ($remaining_cpus>$remaining_nodes);
103 $i++) {
104
105 $remaining_cpus -= $ncpus;
106 $remaining_nodes -= 1;
107
108 # May only have to use part of a node. Check here
109 # for that case.
110 my $used = ($remaining_cpus>=0)
111 ? $ncpus
112 : $ncpus+$remaining_cpus;
113
114 # Increase the allocation.
115 if (defined($allocated{$used})) {
116 $allocated{$used} += 1;
117 } else {
118 $allocated{$used} = 1;
119 }
120 }
121
122 # If we can fill out the rest without restricting the
123 # number of cpus on a node, do so.
124 if ($remaining_cpus<=$remaining_nodes &&
125 $remaining_cpus>0) {
126
127 my $used = 1;
128 if (defined($allocated{$used})) {
129 $allocated{$used} += $remaining_cpus;
130 } else {
131 $allocated{$used} = $remaining_cpus;
132 }
133 $remaining_cpus = 0;
134 }
135 }
136 }
137
138 my $first = 1;
139 foreach my $i (sort num_descending keys %allocated) {
140 $line .= "+" unless $first;
141 $line .= "nodes=" if $first;
142 # $line .= "nodes=";
143 $line .= $allocated{$i};
144 # $line .= ":ppn=" . $i unless ($i == 1);
145 $line .= ":ppn=" . $i;
146 $first = 0;
147 }
148 $line .= "\n";
149 }
150
151 return $line;
152 }
153
154
155 sub num_ascending { $a <=> $b; }
156
157
158 sub num_descending { $b <=> $a; }
159

Properties

Name Value
svn:executable *

grid.support@nikhef.nl
ViewVC Help
Powered by ViewVC 1.1.28