/[escript]/trunk/bin/run-escript
ViewVC logotype

Annotation of /trunk/bin/run-escript

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3259 - (hide annotations)
Mon Oct 11 01:48:14 2010 UTC (9 years ago) by jfenwick
File size: 14813 byte(s)
Merging dudley and scons updates from branches

1 jfenwick 2409 #!/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 jfenwick 2568 #set to 1 if performing this is a standalone build and ../../pkg contains the relevant tools
10 jfenwick 2409 STANDALONE=0
11    
12     #set to 1 if this is part of a packaged build (.deb) and files will be installed in standard locations
13     #rather than everything in a single directory
14     #Do not use this together with $STANDALONE
15     STDLOCATION=0
16    
17     #Now we find the location of this script
18     #Note that this location should be absolute but does not need to be unique
19     scriptdir=""
20     CURDIR=`pwd`
21    
22     #Environment vars which control operations:
23     # ESCRIPT_NUM_NODES, ESCRIPT_NUM_PROCS, ESCRIPT_NUM_THREADS, ESCRIPT_HOSTFILE, ESCRIPT_CREATESTDFILES
24    
25 jfenwick 3047 HOSTFILE=/tmp/escript.$USER.$$
26     HOSTFILE2=/tmp/escript2.$USER.$$
27 jfenwick 2409
28     #Begin finding ESCRIPT_ROOT
29 caltinay 2806 if [ $STDLOCATION -ne 0 ]
30 jfenwick 2409 then
31     ESCRIPT_ROOT=/usr/lib/escript
32     else
33     #We don't know the escript root so we need to work it out from the invocation
34     #Need to match if the name contains /
35     if [[ $0 =~ / ]]
36     then
37     # We are not using the PATH to find the script
38     cd `dirname $0`
39     scriptdir=`pwd`
40     cd $CURDIR
41     else
42     # name does not contain / therefore we are using
43     tscriptdir=`which $0`
44 caltinay 3096 if [ $? -ne 0 ]
45 jfenwick 2409 then
46 caltinay 2806 echo "Error! Unable to determine script directory. Exiting."
47     exit 1
48 jfenwick 2409 fi
49     scriptdir=`dirname $tscriptdir`
50     fi
51    
52     cd $scriptdir/..
53     ESCRIPT_ROOT=`pwd`
54     cd ..
55     ESCRIPT_PARENT=`pwd`
56     cd $CURDIR
57    
58     fi
59     ##### End finding ESCRIPT_ROOT ########
60    
61 caltinay 3178 BUILDINFO_FILE=$ESCRIPT_ROOT/lib/buildvars
62     if [ ! -r $BUILDINFO_FILE ]; then
63 caltinay 2806 echo "Error! Unable to read escript build information. Exiting."
64     exit 1
65     fi
66    
67 caltinay 3178 function get_buildvar {
68 jfenwick 3259 echo `grep "^$1=" $BUILDINFO_FILE |cut -d= -f2`
69 caltinay 3178 }
70    
71 jfenwick 2409 PYTHON_MPI_NULL="$ESCRIPT_ROOT/lib/pythonMPI"
72     PYTHON_MPI_REDIRECT="$ESCRIPT_ROOT/lib/pythonMPIredirect"
73     PYTHON_CMD=python
74    
75     # if possible please express paths relative to $ESCRIPT_ROOT unless
76     # they are in an unrelated location
77    
78     EXTRA_DYLD_LIBRARY_PATH=""
79     EXTRA_PATH=$ESCRIPT_ROOT/bin
80     EXTRA_PYTHONPATH=$ESCRIPT_ROOT
81     EXTRA_LD_LIBRARY_PATH=$ESCRIPT_ROOT/lib
82    
83 caltinay 2806 if [ $STANDALONE -eq 1 ]
84 jfenwick 2409 then
85 jfenwick 2530 EXTRA_PATH=$ESCRIPT_PARENT/pkg/python/bin:$EXTRA_PATH
86     EXTRA_LD_LIBRARY_PATH=$ESCRIPT_PARENT/pkg/boost/lib:$ESCRIPT_PARENT/pkg/netcdf/lib/:$EXTRA_LD_LIBRARY_PATH
87 jfenwick 2541 EXTRA_LD_LIBRARY_PATH=$EXTRA_LD_LIBRARY_PATH
88 jfenwick 2530 EXTRA_LD_LIBRARY_PATH=$ESCRIPT_PARENT/pkg/python/lib:$EXTRA_LD_LIBRARY_PATH
89 jfenwick 2541 EXTRA_PYTHONPATH=$ESCRIPT_PARENT/pkg/numpy/lib/python2.6/site-packages:$ESCRIPT_PARENT/pkg/matplotlib/lib/python2.6/site-packages:$EXTRA_PYTHONPATH
90 jfenwick 2409 fi
91    
92 caltinay 3096 #
93     # Add VisIt paths if required
94     #
95 jfenwick 3259 WITH_VISIT=`get_buildvar visit`
96     if [ "$WITH_VISIT" = "1" ]; then
97 caltinay 3096 VISIT_BIN=`which visit`
98     if [ $? -eq 0 ]; then
99     VISIT_PY_PATH=`$VISIT_BIN -env | grep LIBPATH | cut -d= -f2`
100     EXTRA_PYTHONPATH=$EXTRA_PYTHONPATH:$VISIT_PY_PATH
101     EXTRA_LD_LIBRARY_PATH=$EXTRA_LD_LIBRARY_PATH:$VISIT_PY_PATH
102     elif [ ! -z $ESCRIPT_VERBOSE ]; then
103     echo "VisIt module enabled but VisIt not in path!"
104     fi
105     fi
106 jfenwick 2409
107     HELP_TEXT="
108     Usage: escript [options] script.py [arguments...]
109     -n nn number of nodes to use
110 gross 3193 -p np number of MPI processes to spawn per node
111 jfenwick 2409 -t nt number of OpenMP threads to use
112     -f file name of MPI hostfile
113     -c print compile information for escript and exit
114     -V print escript version and exit
115     -i interactive mode
116     -b do not invoke python (run non-python programs)
117     -e print export statements for environment and exit
118     -o redirect output from MPI to files
119     -v print diagnostics
120     -x ..reserved for future use ..
121     script.py Your python script
122     arguments... The optional command-line arguments to your script
123     "
124    
125     if [ "$1" = "--help" ]; then
126     echo "$HELP_TEXT"
127     exit 0
128     fi
129     #=======================================================================================
130    
131     # Avoid bug in hybrid runs with MPT MPI
132    
133    
134     # Parse the command-line options
135     # option e should not be followed by a :
136     while getopts 'bn:p:t:f:h:ecVviox' option
137     do
138     case "$option" in
139     "b") DOBINARY=yes
140     ;;
141     "n") ESCRIPT_NUM_NODES=$OPTARG
142     ;;
143     "p") ESCRIPT_NUM_PROCS=$OPTARG
144     ;;
145     "t") ESCRIPT_NUM_THREADS=$OPTARG
146     ;;
147     "f") ESCRIPT_HOSTFILE=$OPTARG
148     ;;
149     "c") cat $ESCRIPT_ROOT/lib/buildvars
150     exit 0
151     ;;
152 caltinay 3178 "V") echo "escript-development(build "`get_buildvar svn_revision`")"
153 jfenwick 2409 exit 0
154     ;;
155     "h") echo "$HELPTEXT"
156     exit 0
157     ;;
158     "i") DOINTERACTIVE=yes
159     ;;
160     "e") echo "export LD_LIBRARY_PATH=$EXTRA_LD_LIBRARY_PATH:\$LD_LIBRARY_PATH"
161     echo "export PYTHONPATH=$EXTRA_PYTHONPATH:\$PYTHONPATH"
162     echo "export PATH=$EXTRA_PATH:\$PATH"
163 caltinay 2806 if [ "`uname`" = "Darwin" ]
164 jfenwick 2409 then
165     echo "export DYLD_LIBRARY_PATH=$EXTRA_DYLD_LIBRARY_PATH:$EXTRA_LD_LIBRARY_PATH:\$DYLD_LIBRARY_PATH"
166     fi
167     exit 0
168     ;;
169     "o") ESCRIPT_CREATESTDFILES="yes"
170     ;;
171     "v") ESCRIPT_VERBOSE="yes"
172     ;;
173     "x") echo "-x not implemented yet"
174     exit 1
175     ;;
176     ?) echo "$HELP_TEXT"
177     exit 1
178     ;;
179     esac
180     done
181     shift `expr $OPTIND - 1`
182     #==============================================
183     #
184 caltinay 3178 # Read MPI_FLAVOUR and WITH_OPENMP from the buildvars
185 jfenwick 2409 #
186 jfenwick 3259 MPI_FLAVOUR=`get_buildvar mpi`
187     WITH_OPENMP=`get_buildvar openmp`
188 jfenwick 2409
189 caltinay 2806 if [ ! -z $ESCRIPT_VERBOSE ]; then
190     echo "MPI flavour is $MPI_FLAVOUR."
191 jfenwick 3259 if [ "$WITH_OPENMP" = "1" ]; then echo "OpenMP enabled."; fi
192 caltinay 2806 fi
193    
194 jfenwick 2409 #
195     # extend path variables
196     #
197     export PATH=$EXTRA_PATH:$PATH
198     export LD_LIBRARY_PATH=$EXTRA_LD_LIBRARY_PATH:$LD_LIBRARY_PATH
199     export PYTHONPATH=$EXTRA_PYTHONPATH:$PYTHONPATH
200     EXPORT_ENV="PATH,LD_LIBRARY_PATH,PYTHONPATH"
201 caltinay 2806 if [ "`uname`" = "Darwin" ]
202 jfenwick 2409 then
203     export DYLD_LIBRARY_PATH=$EXTRA_DYLD_LIBRARY_PATH:$EXTRA_LD_LIBRARY_PATH:$DYLD_LIBRARY_PATH
204     EXPORT_ENV="$EXPORT_ENV,DYLD_LIBRARY_PATH"
205     fi
206 caltinay 2806 if [ ! -z $ESCRIPT_VERBOSE ]
207 jfenwick 2409 then
208     echo "PATH = $PATH "
209     echo "LD_LIBRARY_PATH = $LD_LIBRARY_PATH "
210     echo "PYTHONPATH = $PYTHONPATH "
211     if [ ! -z $DYLD_LIBRARY_PATH ]; then echo "DYLD_LIBRARY_PATH = $DYLD_LIBRARY_PATH "; fi
212     fi
213     #==============================================
214     #
215     # Ensure the variables have sensible values
216     #
217 caltinay 2806 if [ "$MPI_FLAVOUR" = "none" ]
218 jfenwick 2409 then
219     if [ ! -z $ESCRIPT_NUM_NODES ]
220     then
221     echo "Warning: MPI disabled but number of nodes set. Option ignored."
222     fi
223     if [ ! -z $ESCRIPT_NUM_PROCS ]
224     then
225     echo "Warning: MPI disabled but number of processors per node set. Option ignored."
226     fi
227     if [ ! -z $ESCRIPT_HOSTFILE ]
228     then
229     echo "Warning: MPI disabled but host file is given. Option ignored."
230     fi
231     ESCRIPT_NUM_NODES=1
232     ESCRIPT_NUM_PROCS=1
233     else
234 jfenwick 3056 # use the PBS_NODEFILE if not otherwise specified
235     if [[ ( ! -z $PBS_NODEFILE ) && ( -z $ESCRIPT_HOSTFILE ) ]]
236     then
237 caltinay 3178 ESCRIPT_HOSTFILE=$PBS_NODEFILE
238 jfenwick 3056 fi
239    
240 jfenwick 2409 if [ ! -z $ESCRIPT_HOSTFILE ]
241     then
242     if [ -f $ESCRIPT_HOSTFILE ]
243     then
244     cat $ESCRIPT_HOSTFILE | sort -u > $HOSTFILE
245     NUM_HOSTS=`cat $HOSTFILE | wc -l`
246     if [ ! -z $ESCRIPT_NUM_NODES ]
247     then
248     if [ $NUM_HOSTS -ne $ESCRIPT_NUM_NODES ]
249     then
250     echo "number of hosts selected in the host file $ESCRIPT_HOSTFILE needs to match the requested number of nodes $ESCRIPT_NUM_NODES."
251     exit 1
252     fi
253     else
254     ESCRIPT_NUM_NODES=$NUM_HOSTS
255     fi
256     else
257     echo "cannot find hostfile $ESCRIPT_HOSTFILE."
258     exit 1
259     fi
260     else
261     HOSTFILE=''
262     fi
263    
264     if [ -z $ESCRIPT_NUM_NODES ]
265     then
266 caltinay 3178 ESCRIPT_NUM_NODES=1
267 jfenwick 2409 fi
268    
269     if [ -z $ESCRIPT_NUM_PROCS ]
270     then
271 caltinay 3178 ESCRIPT_NUM_PROCS=1
272 jfenwick 2409 fi
273    
274 caltinay 2806 if [ ! -z $ESCRIPT_VERBOSE ]
275 jfenwick 2409 then
276 caltinay 3178 echo "ESCRIPT_NUM_NODES = $ESCRIPT_NUM_NODES "
277     echo "ESCRIPT_NUM_PROCS = $ESCRIPT_NUM_PROCS "
278 jfenwick 2409 fi
279     fi
280    
281 jfenwick 3259 if [ "$WITH_OPENMP" = "1" ]
282 jfenwick 2409 then
283     if [ -z $ESCRIPT_NUM_THREADS ]
284     then
285     ESCRIPT_NUM_THREADS=$OMP_NUM_THREADS
286     if [ -z $ESCRIPT_NUM_THREADS ]
287     then
288     ESCRIPT_NUM_THREADS=1
289     fi
290     fi
291     if [ ! -z $ESCRIPT_VERBOSE ]
292     then
293     echo "ESCRIPT_NUM_THREADS is $ESCRIPT_NUM_THREADS."
294     fi
295     else
296     if [[ ( ! -z $ESCRIPT_NUM_THREADS ) && ( $ESCRIPT_NUM_THREADS != 1 ) ]]
297     then
298     echo "Warning: OpenMP is disabled but number of threads requested is $ESCRIPT_NUM_THREADS!=1. Running without threads."
299     fi
300     ESCRIPT_NUM_THREADS=1
301     fi
302     #
303     # Now we compute total number of Processes
304     #
305     (( TOTPROC=$ESCRIPT_NUM_NODES * $ESCRIPT_NUM_PROCS))
306     if [ $? -ne 0 ] #Some compute error
307     then #This could happen if the args were not a number
308 caltinay 3178 echo "expression of total number of processors = $ESCRIPT_NUM_NODES * $ESCRIPT_NUM_PROCS is not numerical."
309     exit 1
310 jfenwick 2409 fi
311    
312     #
313     # Test to ensure people aren't trying to combine interactive and multi-process
314     #
315     if [[ ( ( ! -z $DOINTERACTIVE ) || ( $# -eq 0 ) ) && ( $TOTPROC -gt 1) ]]
316     then
317 caltinay 3178 echo "Interactive mode cannot be used with more than one process"
318     exit 1
319 jfenwick 2409 fi
320    
321     if [ $TOTPROC -gt 1 ]
322     then
323 caltinay 3178 if [ "$ESCRIPT_CREATESTDFILES" = "yes" ]
324     then
325     PYTHON_MPI=$PYTHON_MPI_REDIRECT
326     else
327     PYTHON_MPI=$PYTHON_MPI_NULL
328     fi
329 jfenwick 2409 else
330     PYTHON_MPI=$PYTHON_MPI_NULL
331     fi
332     #=========================================================================================================
333     # Must have at least one command-line arg: the python script
334     if [ $# -eq 0 ]
335     then
336 caltinay 3178 if [ ! -z $DOBINARY ]
337     then
338     echo "No program to run was specified. Exiting."
339     exit 1
340     else
341     DOINTERACTIVE="yes"
342     fi
343 jfenwick 2409 fi
344    
345     #=========================================================================================================
346     if [ ! -z $DOBINARY ]
347     then
348     EXEC_CMD="$@"
349     else
350 caltinay 3178 # Check to see if the python version we were compiled with matches the
351     # one of PYTHON_CMD.
352 jfenwick 3259 compversion=`get_buildvar python_version`
353 caltinay 3178 intversion=`$PYTHON_CMD -c 'import sys;print "%d.%d.%d"%(sys.version_info[0], sys.version_info[1], sys.version_info[2])'`
354     if [ "$compversion" != "$intversion" ]
355     then
356     echo "Python versions do not match. Escript was compiled for "$compversion"."
357     echo "Current version of Python appears to be "$intversion"."
358     exit 1
359     fi
360 caltinay 2806 if [ "$MPI_FLAVOUR" = "none" ]
361 jfenwick 2409 then
362 caltinay 3178 if [ ! -z $DOINTERACTIVE ]
363 jfenwick 2409 then
364     EXEC_CMD="$PYTHON_CMD -i $@"
365     else
366     EXEC_CMD="$PYTHON_CMD $@"
367     fi
368     else
369 caltinay 3178 if [ ! -z $DOINTERACTIVE ]
370 gross 2865 then
371     EXEC_CMD="$PYTHON_MPI -i $@"
372     else
373     EXEC_CMD="$PYTHON_MPI $@"
374     fi
375 jfenwick 2409 fi
376     fi
377     if [ ! -z $ESCRIPT_VERBOSE ]; then echo "Command to be executed is \"$EXEC_CMD\"."; fi
378     #===============================================================================================
379     #
380     # now we start to spwan things:
381     #
382 jfenwick 3259 if [ "$WITH_OPENMP" = "1" ]
383 jfenwick 2409 then
384     export OMP_NUM_THREADS=$ESCRIPT_NUM_THREADS
385     EXPORT_ENV="$EXPORT_ENV,OMP_NUM_THREADS"
386     fi
387     EXIT_CODE=1
388     #=============== no MPI ===================================
389 caltinay 2806 if [ "$MPI_FLAVOUR" = "none" ]
390 jfenwick 2409 then
391     $EXEC_CMD
392     EXIT_CODE=$?
393     #=============== OpenMPI ===================================
394 caltinay 2806 elif [ "$MPI_FLAVOUR" = "OPENMPI" ]
395 jfenwick 2409 then
396     if [ ! -z $HOSTFILE ]
397     then
398     HOST_LIST=`awk 'BEGIN{S=""}{if (S == "") { S = $0 } else {S = S "," $0}}END{print S}' $HOSTFILE`
399 gross 2905 CMD="mpirun --gmca mpi_warn_on_fork 0 -x ${EXPORT_ENV//,/ -x } --bynode -np $TOTPROC --host $HOST_LIST $EXEC_CMD"
400 jfenwick 2409 else
401 gross 2905 CMD="mpirun --gmca mpi_warn_on_fork 0 -x ${EXPORT_ENV//,/ -x } -np $TOTPROC $EXEC_CMD"
402 jfenwick 2409 fi
403     if [ ! -z $ESCRIPT_VERBOSE ]; then echo "MPI command is \"$CMD\"."; fi
404     $CMD
405     EXIT_CODE=$?
406    
407     #=============== Intel MPI ===================================
408 caltinay 2806 elif [ "$MPI_FLAVOUR" = "INTELMPI" ]
409 jfenwick 2409 then
410 gross 2510
411 jfenwick 3259 if [ "$WITH_OPENMP" = "1" ]
412 gross 2510 then
413     export I_MPI_PIN_DOMAIN=omp
414     EXPORT_ENV="$EXPORT_ENV, I_MPI_PIN_DOMAIN"
415     fi
416    
417 jfenwick 2409 if [ ! -z $HOSTFILE ]
418     then
419     mpdboot -n $ESCRIPT_NUM_NODES -r ssh -f $HOSTFILE
420     if [ $? -ne 0 ]
421     then
422     echo "mpdboot with host file $ESCRIPT_HOSTFILE for $ESCRIPT_NUM_NODES nodes failed."
423     exit 1
424     else
425     if [ ! -z $ESCRIPT_VERBOSE ]; then echo "mpdboot was started with host file $ESCRIPT_HOSTFILE for $ESCRIPT_NUM_NODES nodes."; fi
426     fi
427 gross 2866 else
428     mpdboot -n 1 -r ssh
429     if [ $? -ne 0 ]
430     then
431     echo "mpdboot failed."
432     exit 1
433     else
434     if [ ! -z $ESCRIPT_VERBOSE ]; then echo "mpdboot was started."; fi
435     fi
436 jfenwick 2409 fi
437     CMD="mpiexec -perhost $ESCRIPT_NUM_PROCS -envall -n $TOTPROC $EXEC_CMD"
438     if [ ! -z $ESCRIPT_VERBOSE ]; then echo "MPI command is \"$CMD\"."; fi
439     $CMD
440     EXIT_CODE=$?
441 gross 2866 mpdallexit
442     if [ ! -z $ESCRIPT_VERBOSE ]; then echo "mpdallexit executed."; fi
443 jfenwick 2409 #=============== SGI's MPIMPT ===================================
444 caltinay 2806 elif [ "$MPI_FLAVOUR" = "MPT" ]
445 jfenwick 2409 then
446     export MPI_NUM_MEMORY_REGIONS=0
447     EXPORT_ENV="$EXPORT_ENV,MPI_NUM_MEMORY_REGIONS"
448     if [ ! -z $HOSTFILE ]
449     then
450     HOST_LIST=`awk 'BEGIN{S=""}{if (S == "") { S = $0 } else {S = S "," $0}}END{print S}' $HOSTFILE`
451 gross 2866 CMD="mpirun $HOST_LIST -np $ESCRIPT_NUM_PROCS $EXEC_CMD"
452 jfenwick 2409 else
453     CMD="mpirun -np $TOTPROC $EXEC_CMD"
454     fi
455     if [ ! -z $ESCRIPT_VERBOSE ]; then echo "MPI command is \"$CMD\"."; fi
456     $CMD
457     EXIT_CODE=$?
458     #=============== MPICH ===================================
459 caltinay 2806 elif [ "$MPI_FLAVOUR" = "MPICH" ]
460 jfenwick 2409 then
461     if [ ! -z $HOSTFILE ]
462     then
463     touch $HOSTFILE2
464     for (( i=1;i<=$ESCRIPT_NUM_PROCS;i+=1 )) ; do cat $HOSTFILE >> $HOSTFILE2 ; done
465     CMD="mpirun -machinefile $HOSTFILE2 -np $TOTPROC $EXEC_CMD"
466     else
467     CMD="mpirun -np $TOTPROC $EXEC_CMD"
468     fi
469     if [ ! -z $ESCRIPT_VERBOSE ]; then echo "MPI command is \"$CMD\"."; fi
470     $CMD
471     EXIT_CODE=$?
472     #=============== MPICH2 ===================================
473 caltinay 2806 elif [ "$MPI_FLAVOUR" = "MPICH2" ]
474 jfenwick 2409 then
475     if [ ! -z $HOSTFILE ]
476     then
477     mpdboot -n $ESCRIPT_NUM_NODES -r ssh -f $HOSTFILE
478     if [ $? -ne 0 ]
479     then
480     echo "mpdboot with host file $ESCRIPT_HOSTFILE for $ESCRIPT_NUM_NODES nodes failed."
481     exit 1
482     else
483     if [ ! -z $ESCRIPT_VERBOSE ]; then echo "mpdboot was started with host file $ESCRIPT_HOSTFILE for $ESCRIPT_NUM_NODES nodes."; fi
484     fi
485 gross 2866 else
486     mpdboot -n 1 -r ssh
487     if [ $? -ne 0 ]
488     then
489     echo "mpdboot failed."
490     exit 1
491     else
492     if [ ! -z $ESCRIPT_VERBOSE ]; then echo "mpdboot was started."; fi
493     fi
494 jfenwick 2409 fi
495     CMD="mpiexec -genvlist $EXPORT_ENV -np $TOTPROC $EXEC_CMD"
496     if [ ! -z $ESCRIPT_VERBOSE ]; then echo "MPI command is \"$CMD\"."; fi
497     $CMD
498     EXIT_CODE=$?
499 gross 2866 mpdallexit
500     if [ ! -z $ESCRIPT_VERBOSE ]; then echo "mpdallexit executed."; fi
501 jfenwick 2409 else
502 caltinay 2806 echo "unknown MPI flavour '$MPI_FLAVOUR'."
503 jfenwick 2409 fi
504     exit $EXIT_CODE

Properties

Name Value
svn:executable *
svn:mergeinfo /branches/lapack2681/bin/escript:2682-2741 /branches/restext/bin/escript:2610-2624 /branches/stage3.0/bin/escript:2569-2590 /release/3.0/bin/escript:2591-2601

  ViewVC Help
Powered by ViewVC 1.1.26