Michael, You make good points.
I will look into the Module you list below. Thanks, - Ross > -----Original Message----- > From: Michael Wild [mailto:them...@gmail.com] > Sent: Wednesday, January 14, 2009 2:43 AM > To: Bartlett, Roscoe A > Cc: cmake@cmake.org > Subject: Re: [CMake] History and ideas behind FindMPI.cmake? > > > On 13. Jan, 2009, at 15:17, Bartlett, Roscoe A wrote: > > > > In Trilinos, an MPI configured build creates all MPI > executables (in > > some sense). Also, most Trilinos software is set up to > automatically > > check to see if MPI is initialized or not and will run correctly in > > serial mode with MPI enabled but not initialized. > > > > Also, most newer MPI implementations that I have used allow you to > > build with MPI support but never call MPI_Init(...) and > never have to > > use mpiexec/mpirun in order to run a serial executable (as > long as you > > don't call MPI functions). That is how you can get away > with defining > > CMAKE_[C,CXX,Fortran]_COMPILER as the MPI compiler > wrappers. Also, if > > you only use try_compile(...) tests at configure time, then > you will > > never have any problem with this. Even with try_run(...), > as long as > > these tests don't call MPI functions then they should work > just fine > > also with most newer MPI implementations. > > > > Lastly, our project Trilinos does not really define *any* > executables > > except for tests and examples. To set up even single- process > > tests/examples to work with MPI is trivial. There is a > single object > > that you have to create in main(...) like: > > > > Teuchos::GlobalMPISession mpiSession(&argc, &argv); > > > > and you just have to run the test/example with > mpirun/mpiexec with one > > process in case your MPI implementation requires that you do so. > > > > The C++ class Teuchos::GlobalMPISession works with both MPI > and non- > > MPI enabled software. > > That might be true for Trilinos, but not necessarily for > other projects. I can easily imagine a project where the main > executable/ library is built using MPI, but some > helper/utility programs are not. > There is no point in linking them against MPI. This not only > makes startup slower, but also increases memory footprint. In > some cases it might even be harmful. > > > > > > >>> 4) The standard MPI install structure of many MPI implementations > >>> (e.g. MPICH, OpenMPI, LAM MPI etc.) of prefix/[include, > >> bin] will be > >>> exploited and searching from MPI_BASE_DIR (which is set by the > >>> client) will be done. In this way, you can just set a > single cache > >>> variable on most systems and get MPI totally set up. > >> > >> This won't work at all. See the --includedir and --libdir > options of > >> the OpenMPI configure script. Your proposal will force > these values > >> to the default, making too many assumptions. > > > > You misunderstood. This would not require that MPI must be > installed > > in PREFIX/[include, bin, lib] but if it is, then the user > could just > > give the base directory. It is not hard to set this up at > all and I > > am surprised that the other CMake find modules don't do this. > > However, if we are going to just use mpicc/mpiCC/mpiC++/ > > mpif77 etc and mpirun/mpiexec then we just need the 'bin' directory > > and can thrown the rest of this out. > > > It's not necessary. The user can define CMAKE_PREFIX_PATH and > this has the effect you want. > > > > > > > >>> These days, I don't know if anyone still uses raw compilers > >> and then > >>> tries to manually pass in the compiler options and link > >> libraries. > >>> We can still support such a thing but I think this is the > >> 1% exception > >>> instead of the rule. Am I wrong about this? > >> > >> I know of at least one large project which does not use > the wrappers > >> because the developers abstracted the communications into separate > >> libraries, one for MPI, one for GAMMA and one for LVM. The > user has > >> then the choice of which library should be used when he starts the > >> program. Couldn't do that with your proposal. > > > > Is this a runtime option or a configure-time option in this "large > > project"? If it is a runtime option, then you have to at > least build > > in support for MPI so using the MPI compiler wrappers is > just fine. > > If it is a configure-time option, then you can configure with and > > without MPI. That is exactly what Trilinos does. You can build a > > serial version of Trilinos with and without MPI. If there was some > > other great communication layer we could also wrap that and > use that > > with most of Trilinos (most of Trilinos uses thin abstract adapters > > for communication and is not directly tied to MPI). > > It is a runtime option. Before you start a solver you can > choose which implementation of the communications library you > want. One of the reasons I don't like linking against all > possible parallel communications libraries is our > heterogeneous cluster. On some compute nodes PVM is > available, but not MPI and vice versa. There are also > differenc MPI implementations around (OpenMPI, Quadrics, > etc.) The queueing system automagically submits the job to > the right queue. > Problem is now, that if e.g. everything is linked against > OpenMPI but is submitted to a queue where only PVM or > Quadrics MPI is installed, the program won't even start. > > If you really want to use an MPI compiler for everything, > then you could use the following FindMpiCompilers.cmake > module I came up with: > > # - Find the MPI compiler wrappers > # This module locates the MPI compiler wrappers (mpicc, mpicxx/mpic++, > mpif77 and mpif90). > # It is useful if one wants to force a project to use the MPI > compiler wrappers as default # compilers. > # > # The module has the following COMPONENTS: > # C searches for mpicc > # CXX searches for mpicxx and mpic++ > # F77 searches for mpif77 > # F90 searches for mpif90 > # If no components are specified, all of them are enabled by default. > # > # The module sets the following cache variables (if the > corresponding module is enabled): > # MPICOMPILERS_C the mpicc compiler > # MPICOMPILERS_CXX the mpicxx/mpic++ compiler # > MPICOMPILERS_F77 the mpif77 compiler # MPICOMPILERS_F90 > the mpif90 compiler # # If the user wishes to specify a > specific compiler wrapper (e.g. one which is # using a > non-standard name or one which is not found on the path) can > do so # by setting the corresponding MPICOMPILERS_XXX > variable (e.g. using the # -D flag the first time CMake is > run). It also honours environment variables # by the same > name. The CC, CXX and similar variables are not considered by > # design. > # > # If the module is not REQUIRED make sure to check the > MPICOMPILERS_XXX # variables. > # > # Beware that although the module can search for both the > mpif77 and mpif90 # compiler wrappers, CMake only knows the > CMAKE_Fortran_COMPILER variable # which means that you can't > use both of the wrappers in the same project. This, # > however, probably is not a big issue as Fortran90 is a > superset of # Fortran77 and all Fortran90 compilers I know of > also process Fortran77 # sources. > # > # An example CMakeLists.txt could look like this: > # > # # prevent CMake from compiler detection using NONE as the > project language # project( some_project NONE ) # # > cmake_minimum_required( VERSION 2.6 ) # # # find the mpi > compiler wrappers # find_package( MpiCompilers REQUIRED CXX > F77 ) # # # set the CMAKE_XXX_COMPILER variables # set( > CMAKE_CXX_COMPILER ${MPICOMPILERS_CXX} ) # set( > CMAKE_Fortran_COMPILER ${MPICOMPILERS_F77} ) # # enable the > corresponding languages to do the compiler detection # > enable_language( CXX ) # enable_language( Fortran ) # # # > now go on as usual # add_executable( fancy_mpi_program > source1.cxx source2.f ) > > # Copyright 2009 Michael Wild <them...@users.sourceforge.net> > > # check the components that are requested if( > MpiCompilers_FIND_COMPONENTS ) > set( __MpiCompilers_C FALSE ) > set( __MpiCompilers_CXX FALSE ) > set( __MpiCompilers_F77 FALSE ) > set( __MpiCompilers_F90 FALSE ) > foreach( __MpiCompilers_comp ${MpiCompilers_FIND_COMPONENTS} ) > if( __MpiCompilers_comp STREQUAL C ) > set( __MpiCompilers_C TRUE ) > elseif( __MpiCompilers_comp STREQUAL CXX ) > set( __MpiCompilers_CXX TRUE ) > elseif(__MpiCompilers_comp STREQUAL F77 ) > set( __MpiCompilers_F77 TRUE ) > elseif( __MpiCompilers_comp STREQUAL F90 ) > set( __MpiCompilers_F90 TRUE ) > else( __MpiCompilers_comp STREQUAL C ) > message( FATAL_ERROR "Unknown component > ${__MpiCompilers_comp}" ) > endif( __MpiCompilers_comp STREQUAL C ) > endforeach( __MpiCompilers_comp ) > else( MpiCompilers_FIND_COMPONENTS ) > # by default turn all components on > set( __MpiCompilers_C TRUE ) > set( __MpiCompilers_CXX TRUE ) > set( __MpiCompilers_F77 TRUE ) > set( __MpiCompilers_F90 TRUE ) > endif( MpiCompilers_FIND_COMPONENTS ) > > # find the requested compilers and set up the list # of > required variables set( __MpiCompilers_REQVARS "" ) set( > __MpiCompilers_FOUNDCOMPILERS "" ) if( __MpiCompilers_C ) > if( NOT "$ENV{MPICOMPILERS_C}" STREQUAL "" ) > set( MPICOMPILERS_C $ENV{MPICOMPILERS_C} CACHE FILEPATH > "Path to the MPI C compiler" ) > else( NOT "$ENV{MPICOMPILERS_C}" STREQUAL "" ) > find_program( MPICOMPILERS_C mpicc DOC "Path to the MPI > C compiler" ) > endif( NOT "$ENV{MPICOMPILERS_C}" STREQUAL "" ) > list( APPEND __MpiCompilers_REQVARS MPICOMPILERS_C ) > set( __MpiCompilers_FOUNDCOMPILERS "$ > {__MpiCompilers_FOUNDCOMPILERS} ${MPICOMPILERS_C}" ) endif( > __MpiCompilers_C ) if( __MpiCompilers_CXX ) > if( NOT "$ENV{MPICOMPILERS_CXX}" STREQUAL "" ) > set( MPICOMPILERS_CXX $ENV{MPICOMPILERS_CXX} CACHE > FILEPATH "Path to the MPI C++ compiler" ) > else( NOT "$ENV{MPICOMPILERS_CXX}" STREQUAL "" ) > find_program( MPICOMPILERS_CXX NAMES mpicxx mpic++ DOC > "Path to the MPI C++ compiler" ) > endif( NOT "$ENV{MPICOMPILERS_CXX}" STREQUAL "" ) > list( APPEND __MpiCompilers_REQVARS MPICOMPILERS_CXX ) > set( __MpiCompilers_FOUNDCOMPILERS "$ > {__MpiCompilers_FOUNDCOMPILERS} ${MPICOMPILERS_CXX}" ) endif( > __MpiCompilers_CXX ) if( __MpiCompilers_F77 ) > if( NOT "$ENV{MPICOMPILERS_F77}" STREQUAL "" ) > set( MPICOMPILERS_F77 $ENV{MPICOMPILERS_F77} CACHE > FILEPATH "Path to the MPI F77 compiler" ) > else( NOT "$ENV{MPICOMPILERS_F77}" STREQUAL "" ) > find_program( MPICOMPILERS_F77 mpif77 DOC "Path to the > MPI F77 compiler" ) > endif( NOT "$ENV{MPICOMPILERS_F77}" STREQUAL "" ) > list( APPEND __MpiCompilers_REQVARS MPICOMPILERS_F77 ) > set( __MpiCompilers_FOUNDCOMPILERS "$ > {__MpiCompilers_FOUNDCOMPILERS} ${MPICOMPILERS_F77}" ) endif( > __MpiCompilers_F77 ) if( __MpiCompilers_F90 ) > if( NOT "$ENV{MPICOMPILERS_F90}" STREQUAL "" ) > set( MPICOMPILERS_F90 $ENV{MPICOMPILERS_F90} CACHE > FILEPATH "Path to the MPI F90 compiler" ) > else( NOT "$ENV{MPICOMPILERS_F90}" STREQUAL "" ) > find_program( MPICOMPILERS_F90 mpif90 DOC "Path to the > MPI F77 compiler" ) > endif( NOT "$ENV{MPICOMPILERS_F90}" STREQUAL "" ) > list( APPEND __MpiCompilers_REQVARS MPICOMPILERS_F90 ) > set( __MpiCompilers_FOUNDCOMPILERS "$ > {__MpiCompilers_FOUNDCOMPILERS} ${MPICOMPILERS_F90}" ) endif( > __MpiCompilers_F90 ) > > mark_as_advanced( ${__MpiCompilers_REQVARS} ) > > # handle standard arguments > include( FindPackageHandleStandardArgs ) > find_package_handle_standard_args( MpiCompilers DEFAULT_MSG > __MpiCompilers_FOUNDCOMPILERS ${__MpiCompilers_REQVARS} ) > > > > > > > The argument for directly using the MPI compiler wrappers is > > compelling (and that is why almost everyone I know uses them). > > Yes, for simple projects. NOT for mixed projects. > > Michael > _______________________________________________ CMake mailing list CMake@cmake.org http://www.cmake.org/mailman/listinfo/cmake