1 |
#!/bin/bash |
2 |
|
3 |
# Escript/Finley wrapper for python |
4 |
# Sets LD_LIBRARY_PATH and PYTHONPATH and then runs either python or the MPI launcher |
5 |
|
6 |
#Extra paths can be configured about a page further down |
7 |
#Search for EXTRA_PATH="" |
8 |
|
9 |
#set to 1 if performing this is a standalone build and /packages contains the relevant tools |
10 |
STANDALONE=0 |
11 |
|
12 |
#Now we find the location of this script |
13 |
#Note that this location should be absolute but does not need to be unique |
14 |
scriptdir="" |
15 |
CURDIR=`pwd` |
16 |
|
17 |
#Environment vars which control operations: |
18 |
# ESCRIPT_NUM_NODES, ESCRIPT_NUM_PROC, ESCRIPT_NUM_THREADS, ESCRIPT_HOSTFILE, ESCRIPT_STDFILES |
19 |
|
20 |
|
21 |
#Need to match if the name contains / |
22 |
if [[ $0 =~ / ]] |
23 |
then |
24 |
# We are not using the PATH to find the script |
25 |
cd `dirname $0` |
26 |
scriptdir=`pwd` |
27 |
cd $CURDIR |
28 |
else |
29 |
# name does not contain / therefore we are using |
30 |
tscriptdir=`which $0` |
31 |
if [ $? != 0 ] |
32 |
then |
33 |
echo "Error unable to determine script directory. Exiting." |
34 |
exit 1 |
35 |
fi |
36 |
scriptdir=`dirname $tscriptdir` |
37 |
fi |
38 |
|
39 |
cd $scriptdir/.. |
40 |
ESCRIPT_ROOT=`pwd` |
41 |
cd .. |
42 |
ESCRIPT_PARENT=`pwd` |
43 |
cd $CURDIR |
44 |
|
45 |
##### End finding ESCRIPT_ROOT ######## |
46 |
|
47 |
# if possible please express paths relative to $ESCRIPT_ROOT unless |
48 |
# they are in an unrelated location |
49 |
|
50 |
EXTRA_PATH="" |
51 |
EXTRA_LD_LIBRARY_PATH="" |
52 |
EXTRA_DYLD_LIBRARY_PATH="" |
53 |
EXTRA_PYTHONPATH="" |
54 |
|
55 |
if [ $STANDALONE == 1 ] |
56 |
then |
57 |
EXTRA_PATH=$ESCRIPT_PARENT/packages/python/bin:$EXTRA_PATH |
58 |
EXTRA_LD_LIBRARY_PATH=$ESCRIPT_PARENT/packages/boost/lib:$ESCRIPT_PARENT/packages/netcdf/lib/:$EXTRA_LD_LIBRARY_PATH |
59 |
EXTRA_LD_LIBRARY_PATH=$ESCRIPT_PARENT/packages/vtk/lib/vtk-5.2:$ESCRIPT_PARENT/packages/mesa/lib:$EXTRA_LD_LIBRARY_PATH |
60 |
EXTRA_LD_LIBRARY_PATH=$ESCRIPT_PARENT/packages/python/lib:$EXTRA_LD_LIBRARY_PATH |
61 |
EXTRA_PYTHONPATH=$ESCRIPT_PARENT/packages/numarray/lib:$ESCRIPT_PARENT/packages/vtk/lib/python2.6/site-packages:$EXTRA_PYTHONPATH |
62 |
fi |
63 |
|
64 |
# For stand-alone builds this will need to be changed |
65 |
PYTHON_CMD=python |
66 |
|
67 |
EXTRA_PYTHONPATH=$ESCRIPT_ROOT:$EXTRA_PYTHONPATH |
68 |
EXTRA_LD_LIBRARY_PATH=$ESCRIPT_ROOT/lib:$EXTRA_LD_LIBRARY_PATH |
69 |
|
70 |
|
71 |
HELP_TEXT=" |
72 |
Usage: escript [options] script.py [arguments...] |
73 |
-n nn number of nodes to use |
74 |
-p np number of MPI processes to spawn |
75 |
-t nt number of OpenMP threads to use |
76 |
-f file name of MPI hostfile |
77 |
-c print compile information for escript and exit |
78 |
-V print escript version and exit |
79 |
-i interactive mode |
80 |
-e print export statements for environment and exit |
81 |
-o redirect output from MPI to files |
82 |
-v print diagnostics |
83 |
-x ..reserved for future use .. |
84 |
script.py Your python script |
85 |
arguments... The optional command-line arguments to your script |
86 |
" |
87 |
|
88 |
if [ "$1" = "--help" ]; then |
89 |
echo "$HELP_TEXT" |
90 |
exit 0 |
91 |
fi |
92 |
|
93 |
|
94 |
|
95 |
# Avoid bug in hybrid runs with MPT MPI |
96 |
export MPI_NUM_MEMORY_REGIONS=0 |
97 |
|
98 |
# Try to guess the MPI launcher (mpirun unless in PBS batch job in which case mpiexec) |
99 |
mpi_launcher='mpirun -np' |
100 |
if [ $?PBS_ENVIRONMENT ]; then |
101 |
if [ "X_$PBS_ENVIRONMENT" = "X_PBS_BATCH" ]; then |
102 |
mpi_launcher='mpiexec -n' |
103 |
fi |
104 |
fi |
105 |
|
106 |
PYTHON_MPI="$ESCRIPT_ROOT/lib/pythonMPI" |
107 |
OMP_NUM_THREADS=1 |
108 |
MPI_NUM_PROCS=1 |
109 |
|
110 |
# Parse the command-line options |
111 |
# option e should not be followed by a : |
112 |
while getopts 'n:p:t:f:h:ecVviox' option |
113 |
do |
114 |
case "$option" in |
115 |
"n") ESCRIPT_NUM_NODES=$OPTARG |
116 |
;; |
117 |
"p") ESCRIPT_NUM_PROC=$OPTARG |
118 |
;; |
119 |
"t") ESCRIPT_NUM_THREADS=$OPTARG |
120 |
;; |
121 |
"f") ESCRIPT_HOSTFILE=$OPTARG |
122 |
;; |
123 |
"c") cat $ESCRIPT_ROOT/lib/buildvars |
124 |
exit 0 |
125 |
;; |
126 |
"V") echo "escript-pre2.0(build "`grep svn_revision $ESCRIPT_ROOT/lib/buildvars |cut -d= -f2`")" |
127 |
exit 0 |
128 |
;; |
129 |
"h") echo "$HELPTEXT" |
130 |
exit 0 |
131 |
;; |
132 |
"i") DOINTERACTIVE=yes |
133 |
;; |
134 |
"e") echo "export LD_LIBRARY_PATH=$EXTRA_LD_LIBRARY_PATH:\$LD_LIBRARY_PATH" |
135 |
echo "export PYTHONPATH=$EXTRA_PYTHONPATH:\$PYTHONPATH" |
136 |
echo "export PATH=$EXTRA_PATH:\$PATH" |
137 |
if [ `uname` == Darwin ] |
138 |
then |
139 |
echo "export DYLD_LIBRARY_PATH=$EXTRA_DYLD_LIBRARY_PATH:$EXTRA_LD_LIBRARY_PATH:\$DYLD_LIBRARY_PATH" |
140 |
fi |
141 |
exit 0 |
142 |
;; |
143 |
"o") ESCRIPT_STDFILES="yes" |
144 |
;; |
145 |
"v") echo "Diagnostics:" |
146 |
exit 0 |
147 |
;; |
148 |
"x") echo "-x not implemented yet" |
149 |
exit 1 |
150 |
;; |
151 |
?) echo "$HELP_TEXT" |
152 |
exit 1 |
153 |
;; |
154 |
esac |
155 |
done |
156 |
shift `expr $OPTIND - 1` |
157 |
|
158 |
|
159 |
|
160 |
|
161 |
export PATH=$EXTRA_PATH:$PATH |
162 |
export LD_LIBRARY_PATH=$EXTRA_LD_LIBRARY_PATH:$LD_LIBRARY_PATH |
163 |
export PYTHONPATH=$EXTRA_PYTHONPATH:$PYTHONPATH |
164 |
if [ `uname` == Darwin ] |
165 |
then |
166 |
export DYLD_LIBRARY_PATH=$EXTRA_DYLD_LIBRARY_PATH:$EXTRA_LD_LIBRARY_PATH:$DYLD_LIBRARY_PATH |
167 |
fi |
168 |
|
169 |
# Check to see if the python version we were compiled with matches the one of PYTHON_CMD |
170 |
if [ -f $ESCRIPT_ROOT/lib/pyversion ] |
171 |
then |
172 |
compversion=`cat $ESCRIPT_ROOT/lib/pyversion` |
173 |
intversion=`python --version 2>&1` |
174 |
if [ "$compversion" != "$intversion" ] |
175 |
then |
176 |
echo "Python versions do not match. Escript was compiled for "$compversion"." |
177 |
echo "Current version of Python appears to be "$intversion"." |
178 |
exit 1 |
179 |
fi |
180 |
fi |
181 |
|
182 |
# Must have at least one command-line arg: the python script |
183 |
if [ $# -eq 0 ]; then |
184 |
echo "No python script specified. Starting python interpreter." |
185 |
fi |
186 |
|
187 |
#Ensure the variables have sensible values |
188 |
if [ -z $ESCRIPT_NUM_NODES ] |
189 |
then |
190 |
ESCRIPT_NUM_NODES=1 |
191 |
fi |
192 |
|
193 |
if [ -z $ESCRIPT_NUM_PROCS ] |
194 |
then |
195 |
ESCRIPT_NUM_PROCS=1 |
196 |
fi |
197 |
|
198 |
if [ -z $ESCRIPT_NUM_THREADS ] |
199 |
then |
200 |
ESCRIPT_NUM_THREADS=$OMP_NUM_THREADS |
201 |
if [ -z $ESCRIPT_NUM_THREADS ] |
202 |
then |
203 |
ESCRIPT_NUM_THREADS=1 |
204 |
fi |
205 |
fi |
206 |
|
207 |
#Now we compute total number of Processes |
208 |
(( TOTPROC=$ESCRIPT_NUM_NODES * $ESCRIPT_NUM_PROCS)) |
209 |
if [ $? -ne 0 ] #Some compute error |
210 |
then #This could happen if the args were not a number |
211 |
ESCRIPT_NUM_NODES=1 |
212 |
ESCRIPT_NUM_PROCS=1 |
213 |
fi |
214 |
|
215 |
# Test to ensure people aren't trying to combine interactive and multi-process |
216 |
|
217 |
if [[ ( ( -z $DOINTERACTIVE ) || ( $# -eq 0 ) ) && ( $TOTPROC -gt 1) ]] |
218 |
then |
219 |
echo "Interactive mode cannot be used with more than one process" |
220 |
exit 1 |
221 |
fi |
222 |
|
223 |
# Using OpenMP? |
224 |
OMP_OPTIONS='' |
225 |
if [ -f "$ESCRIPT_ROOT/lib/Compiled.with.openmp" ]; then |
226 |
# PYTHON_CMD="$mpi_launcher $MPI_NUM_PROCS $PYTHON_MPI" |
227 |
OMP_OPTIONS="env OMP_NUM_THREADS=$ESCRIPT_NUM_THREADS" |
228 |
fi |
229 |
|
230 |
# Using MPI? |
231 |
if [ -f "$ESCRIPT_ROOT/lib/Compiled.with.mpi" ]; then |
232 |
PYTHON_CMD="$mpi_launcher $MPI_NUM_PROCS $PYTHON_MPI" |
233 |
else |
234 |
if [ "$TOTPROC" -ne 1 ]; then |
235 |
echo "Escript/Finley was not compiled for MPI. You can not use the -n and -p options." |
236 |
exit 1 |
237 |
fi |
238 |
fi |
239 |
|
240 |
set -x |
241 |
$OMP_OPTIONS $PYTHON_CMD "$@" |
242 |
|