Merge branch 'charm' of charmgit:charm into charm
[charm.git] / src / arch / mpi / charmrun
1 #!/bin/sh
2 #
3 # Conv-host for MPI:
4 #  Translates +pN-style conv-host options into 
5 # mpirun -npN options.
6
7 args=""
8 pes=1
9 ppn=1
10 machinefile=""
11
12 while [ $# -gt 0 ]
13 do
14         case $1 in
15         +ppn|++ppn)
16                 args=$args" +ppn "$2
17                 ppn=$2
18                 shift
19                 ;;
20         +ppn[0-9]*)
21                 args=$args" "$1
22                 ppn=`echo $1 | awk '{print substr($1,5)}'`
23                 ;;
24         ++ppn[0-9]*)
25                 args=$args" "$1
26                 ppn=`echo $1 | awk '{print substr($1,6)}'`
27                 ;;
28         +p)
29                 pes=$2
30                 shift
31                 ;;
32         +pemap)
33                 args=$args" "$1" "$2
34                 shift
35                 ;;
36         +p[0-9]*)
37                 pes=`echo $1 | awk '{print substr($1,3)}'`
38                 ;;
39         -machinefile)
40                 machinefile=$2
41                 args=" "$1" "$2" "$args
42                 shift
43                 ;;
44         *) 
45                 args=$args" "$1
46                 ;;
47         esac
48         shift
49 done
50
51 rem=`expr $pes % $ppn`
52 quot=`expr $pes / $ppn`
53 if [ $rem -ne 0 ];
54 then
55   printf "p = $pes should be a multiple of ppn = $ppn\n"
56   exit 1
57 else
58   pes=$quot
59 fi 
60
61 printf "\nRunning on $pes processors: $args\n"
62
63
64 if [ -n "$PBS_NODEFILE" ]
65 then
66 # we are in a job shell
67   aprun=`which aprun 2>/dev/null`
68   if test -n "$aprun"
69   then
70     echo aprun -n $pes $args
71     $aprun -n $pes $args
72   else
73     mpirun_cmd=`which mpirun 2>/dev/null`
74     if test -n "$mpirun_cmd"
75     then
76       if echo $mpirun_cmd | grep 'mvapich2'  > /dev/null 2>/dev/null
77       then
78         # if daemon not started, start it
79         if ! mpdtrace > /dev/null 2>/dev/null
80         then
81           mvapich2-start-mpd
82         fi
83         mpirun -np $pes $args
84         #    mpdallexit
85       else   # normal case
86         test -z "$machinefile" && args=-machinefile" "$PBS_NODEFILE" "$args
87         echo mpirun -np $pes $args
88         mpirun -np $pes $args
89       fi
90     else
91       echo "Charmrun> can not locate mpirun in order to run the program."
92       exit 1
93     fi
94   fi
95 elif [ -n "$LSB_HOSTS" ]
96 then
97 # Tungsten
98   echo cmpirun -lsf -poll -no_smp -gm_long 200000 $args 
99   cmpirun -lsf -poll -no_smp -gm_long 200000 $args 
100 elif [ -n "$PBS_QUEUE" -o -n "$LSF_QUEUE" ]
101 then
102 # Interactive mode: create, and submit a batch job
103         script="charmrun_script.$$.sh"
104         indir=`pwd`
105         output="$indir/charmrun_script.$$.stdout"
106         result="$indir/charmrun_script.$$.result"
107         rm -f $result
108 # Some machine specific 
109         USE_LSF=0
110 # 10 minutes    
111         walllimit=10
112         queue_stat=qstat
113         queue_qsub=qsub
114         queue_kill=qdel
115         hostname=`hostname`
116         case "$hostname" in
117         turing*.turing.uiuc.edu) 
118                 ppn='#PBS -l nodes='$pes':ppn=1'
119                 extra='-machinefile $PBS_NODEFILE'
120                 ;;
121         tg-login*|honest*.ncsa.uiuc.edu)
122                 # always ppn=2
123                 nodes=`expr \( $pes + 1 \) / 2`
124                 test $pes -eq 1 && ppns=1 || ppns=2
125                 ppn='#PBS -l nodes='$nodes':ppn='$ppns
126                 extra='-machinefile $PBS_NODEFILE'
127                 ;;
128         co-login*.ncsa.uiuc.edu)
129                 mem='#PBS -l mem=500mb'
130                 ncpus="#PBS -l ncpus=$pes"
131                 ;;
132         tun*)
133                 USE_LSF=1
134                 queue_stat=bjobs
135                 queue_qsub=bsub
136                 queue_kill=bkill
137                 ;;
138         abe*)
139                 # always ppn=2
140                 nodes=`expr \( $pes + 1 \) / 2`
141                 test $pes -eq 1 && ppns=1 || ppns=2
142                 ppn='#PBS -l nodes='$nodes':ppn='$ppns
143                 extra='-machinefile $PBS_NODEFILE'
144                 ;;
145         kraken*)
146                 ncores=`expr \( $pes + 11 \) / 12 \* 12`
147                 ncpus="#PBS -l size=$ncores"
148                 ppn=''
149                 ;;
150         *)
151                 ncpus="#PBS -l ncpus=$pes"
152                 ;;
153         esac
154         if test $USE_LSF -eq 0
155         then
156           mpirun=`which aprun 2>/dev/null`
157           npcmd="-n "
158           if test -z "$mpirun"
159           then
160             mpirun=`which mpirun 2>/dev/null`
161             npcmd="-np "
162           fi
163           cat > $script << EOF
164 #!/bin/sh
165 # This is a charmrun-generated PBS batch job script.
166 # The lines starting with #PBS are queuing system flags:
167 #
168 $ppn
169 #
170 $ncpus
171 #
172 #PBS -l walltime=$walllimit:00
173 #
174 $mem
175 #
176 #PBS -q $PBS_QUEUE
177 #
178 #PBS -N autobuild
179 #
180 #PBS -j oe
181 #
182 #PBS -o $output
183
184 cd $indir
185
186 cat \$PBS_NODEFILE
187 echo $mpirun $npcmd $pes $extra $args
188 $mpirun $npcmd $pes $extra $args
189
190 # Save mpirun exit status
191 status=\$?
192 echo \$status > $result
193 EOF
194         else
195 #  use LSF
196           mpirun="cmpirun -lsf -poll -no_smp -gm_long 200000"
197           cat > $script << EOF
198 #!/bin/sh
199 # This is a charmrun-generated PBS batch job script.
200 # The lines starting with #PBS are queuing system flags:
201 #
202 #BSUB -J autobuild
203 #BSUB -W 0:$walllimit
204 #BSUB -n $pes
205 #BSUB -o $output
206
207 cd $indir
208 echo \$LSB_MCPU_HOSTS
209 $mpirun $args
210 # Save mpirun exit status
211 status=\$?
212 echo \$status > $result
213 EOF
214         fi
215
216 End() {
217         echo "Charmrun> $queue_kill $jobid ..."
218         $queue_kill $jobid
219         rm -f $script
220         exit $1
221 }
222
223         echo "Submitting batch job for> $mpirun -np $pes $args"
224         echo " using the command> $queue_qsub $script"
225         chmod 755 $script
226         while [ -z "$jobid" ]
227         do
228           [ $USE_LSF = 0 ] && jobid=`$queue_qsub $script|tail -1`
229           [ $USE_LSF = 1 ] && jobid=`$queue_qsub < $script|tail -1|sed -e 's/[^0-9]*//g'`
230         done
231         echo "Job enqueued under job ID $jobid"
232 # kill job if interrupted
233         trap 'End 1' 2 3
234         retry=0
235 # Wait for the job to complete, by checking its status
236         while [ true ]
237         do
238                 $queue_stat $jobid > tmp.$$
239                 exitstatus=$?
240                 if test -f $output
241                 then
242 # The job is done-- print its output
243                         rm tmp.$$
244 # When job hangs, result file does not exist
245                         test -f $result && status=`cat $result` || status=1
246                         test $status -eq 0 && status=`grep 'End of program' $output > /dev/null 2>&1`
247                         cat $output
248                         rm -f $result
249                         test -f $status && rm -f $script $output
250                         exit $status
251                 fi
252 # The job is still queued or running-- print status and wait
253                 tail -1 tmp.$$
254                 rm tmp.$$
255 # Job ID may not exist now
256                 if test $exitstatus -ne 0
257                 then
258 # retry a few times when error occurs
259                         retry=`expr $retry + 1`
260                         if test $retry -gt 6
261                         then
262                                 echo "Charmrun> too many errors, abort!"
263                                 exit 1
264                         else
265                                 sleep 15
266                         fi
267                 else
268 # job still in queue
269                         retry=0
270                         sleep 20
271                 fi
272         done
273 else
274   mpirun_cmd=`which mpirun 2>/dev/null`
275   if test -n "$mpirun_cmd"
276   then
277     [ -n "$MPI_MACHINEFILE" ] && args=" -machinefile $MPI_MACHINEFILE $args"
278     setarch_cmd=`which setarch 2>/dev/null`
279     if [ -n "$setarch_cmd" -a -x "$setarch_cmd" ]
280     then
281       # Disables randomization of the virtual address  space  (turns  on
282       #          ADDR_NO_RANDOMIZE).
283       cur_arch=`uname -m`
284       echo "charmrun>  $setarch_cmd $cur_arch -R  mpirun -np $pes $args"
285       $setarch_cmd $cur_arch -R  mpirun -np $pes $args
286     else
287       echo "charmrun> mpirun -np $pes $args"
288       mpirun -np $pes $args
289     fi
290   else
291     mpiexec_cmd=`which mpiexec 2>/dev/null`
292     if test -n "$mpiexec_cmd"
293     then
294       echo "charmrun> $mpiexec_cmd -n $pes $args"
295       echo
296       "$mpiexec_cmd" -n $pes $args
297     else
298       echo "Don't know how to run MPI program."
299       exit 1
300     fi
301   fi
302 fi
303
304