Sat, 28 Mar 2009
At ICHEC one of our tasks is to help users build their software on our supercomputers. Mostly we have to change paths, etc. in code bases that are used by a handful of scientists, and we don't want to exacerbate the hard-coded path problem. We also have multiple versions of certain libraries and compilers installed, which we select using modules: to do this, you select your software environment with e.g.
$ module load intel-fc/11.0.082 netcdf/4.0-intelThis selects the compiler version, and library version. Then, this places appropriate paths in $PATH, $LD_LIBRARY_PATH. While this is useful for selecting, eg. compilers, its often not great for many build processes that expect library paths, etc. hard-coded. I also dislike adding random environmental variables: it loses the Single Point Of Truth that describes the configuration. So I've come up with the following pattern.
First, record the modules used (eg. library version) in config.log if configure is used. To do this, add the following to the autoconf file or system headers:
# AC_MODULES_OUTPUT # ----------------- # Check if the system runs 'modules', and if so, record the modules environment in the config.log AC_DEFUN([AC_MODULES_LIST], [AC_CACHE_CHECK[modules output if present],[ac_modules_output], (ac_modules_output=`module list 2>&1`) if test $? eq 0; then AC_MSG_RESULT([Output from 'module list' was:\n $ac_modules_output]) fi ])
Secondly, For all packages, ensure that a pkgconfig package file exists. For example, we have multiple MPI implementations on our SGI system. For MVAPICH, we have a modules file:
stokes2:~$ module show mvapich2-intel ------------------------------------------------------------------- /ichec/modulefiles/mvapich2-intel/1.2p1: module-whatis MVAPICH2 1.2p1 (Intel 11.0.074) conflict mvapich2-gnu mvapich2-intel prepend-path PATH /ichec/packages/mvapich/1.2p1-intel/bin prepend-path LD_LIBRARY_PATH /ichec/packages/mvapich/1.2p1-intel/lib prepend-path MANPATH /ichec/packages/mvapich/1.2p1-intel/share/man prepend-path INCLUDE /ichec/packages/mvapich/1.2p1-intel/include prepend-path CPATH /ichec/packages/mvapich/1.2p1-intel/include prepend-path FPATH /ichec/packages/mvapich/1.2p1-intel/include prepend-path PKG_CONFIG_PATH /ichec/packages/mvapich/1.2p1-intel/share/pkgconfig -------------------------------------------------------------------We add a file mpi.pc to the PKG_CONFIG_PATH for each MPI implementation. So, mpi.pc looks like:
# MPI pkgconfig file for mvapich2-intel
# Normally only used to get variables $prefix, etc.
prefix=/ichec/packages/mvapich/1.2p1-intel
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: mpi
Description: netCDF libraries, include files and development tools
Version: 1.2p1
Libs: -L${libdir} -lmpichf90 -lmpich -lpthread -lrdmacm -libverbs -libumad -lrt
Cflags: -I${includedir}
This then means we can add the following small patch to our target software
(in this case a climate code COSMOS):
#########################################################################
#
# MPI message passing root directory of the chosen compiler
+ # Get default MPI ROOT from the pkgconfig file if possible
+ pkg-config mpi --variable=prefix 2> /dev/null > /dev/null
+ if [ $? -eq 0 ]; then
+ MPIROOT=`pkg-config mpi --variable=prefix`
+ fi
+
if [ $compiler = ifort ]; then
export cc=cc
if [ $CHAN = MPI2 ]; then
- export MPIROOT=/sw/sarge-ia32/mpich2-1.0.4p1-pgi
+ export MPIROOT=${MPIROOT:-/sw/sarge-ia32/mpich2-1.0.4p1-pgi}
elif [ $CHAN = MPI1 ]; then
Such a patch is generic enough to be useful outside our institution, and means the code can build out-of-the-box on many systems. Now to add mpi.pc to Debian ...