Running serial jobs on a parallel queue
The HPCF has traditionally been set up for running parallel jobs.
Despite this it is perfectly easy to run a number of serial jobs on a
queue set up for parallel ones. When you submit a job to the queuing
system you generally have a script
which contains everything you want to be run. When the queuing system
runs your job it allocates the number of cpus you asked for and runs
the script on the first one of these cpus. With a system with two cpus
per node such as maxwell if we want to use more than two cpus we need
to know which other machines have been allocated to us and connect to
them to run jobs on those nodes aswell.
Gridengine as set up on maxwell sets a variable $TMPDIR which is local
to each job and holds the location of a working directory used by the
queuing system for that job.
One of the files in this directory is $TMPDIR/machines which holds a
list of the machines allocated to this job. It will have an entry for
each cpu we have asked for. Since maxwell is a dual cpu machine each
machine name will appear twice. This file is used by mpi to know
which machines it should run on. If we want to run a number of
serial jobs then we can use the file in a very similar way. Once
we know which machines to run jobs on we need to use ssh to connect to that machine and
run the commands we want.
Mpi generally runs the same executable with the same input files on
each cpu. We may want to run the same executable but we will probably
want to use different input files.
Probably the easiest way for us to keep track of this is to number our
input files.
So if we want to run a program analysis
input file input.1 input.2 input.3 input.4 we could do it with
the following script:
#!/bin/sh
j=1
for i in `cat $TMPDIR/machines`
do
ssh $i "cd $PWD; analysis input.$j > output.$j" &
let j=$j+1
done
The problem with the above script
is that it will simply return once it has started all the jobs and they
will then be killed.
We need to develop it a little further so that it keeps track of the
jobs it has spawned and waits for them to finish. The following script
does this.
#!/bin/sh
j=1
for i in `cat $TMPDIR/machines`
do
ssh $i "cd $PWD; analysis input.$j > output.$j" &
# Get the PID of the SSH
let x[$j]=$!
let j=$j+1
done
# Wait for the ssh processes to finish
k=1
while [ $k -lt $j ]
do
wait ${x[$k]}
let k=$k+1
done
The above script if submitted will run as many jobs as cpus of the
queue you have submitted to.
Various modifications could be made to this scheme. If we wanted to run
a number of different programs then you could package these up
into a number of scripts.
For example
script.1
#!/bin/sh
prog1 < inputfile1 > outputfile1
and script.2
#!/bin/sh
prog2 < inputfile2 > outputfile2
The script we submit would then look like
#!/bin/sh
j=1
for i in `cat $TMPDIR/machines`
do
ssh $i "cd $PWD; script.$j" &
let x[$j]=$!
let j=$j+1
done
k=1
while [ $k -lt $j ]
do
wait ${x[$k]}
let k=$k+1
done
One would need to make sure all the scripts are executable with
chmod +x script.*
These scripts do not need to contain just one program. The default run
time for the S queue on
maxwell is 24 hours and so it is to your advantage if your jobs take as
close to 24 hours as you can.
So if each of your programs took 7 hours then you could put 3 of these
into each of your scripts. If a job is running when the 24 hours are
up the queuing system will kill it. If your program needs to run
for more than 24 hours then you may need to look at ways of saving the
state of it and resuming from where it was up to.