From bfd3765462e387dd832ea2120f10252dab1f36ca Mon Sep 17 00:00:00 2001 From: Rossen Apostolov Date: Thu, 12 Aug 2010 10:39:26 +0200 Subject: [PATCH] Updated the CMake scripts for finding CUDA, LibXml2 and MPI with the latest 2.8.2 modules. --- cmake/FindCUDA.cmake | 29 ++++++++- cmake/FindLibXml2.cmake | 44 +++++++------- cmake/FindMPI.cmake | 154 +++++++++++++++++++++++++++++++++--------------- 3 files changed, 154 insertions(+), 73 deletions(-) diff --git a/cmake/FindCUDA.cmake b/cmake/FindCUDA.cmake index 6539057ba9..7099609f83 100644 --- a/cmake/FindCUDA.cmake +++ b/cmake/FindCUDA.cmake @@ -418,6 +418,10 @@ if(NOT "${CUDA_TOOLKIT_ROOT_DIR}" STREQUAL "${CUDA_TOOLKIT_ROOT_DIR_INTERNAL}") unset(CUDA_VERSION CACHE) unset(CUDA_TOOLKIT_INCLUDE CACHE) unset(CUDA_CUDART_LIBRARY CACHE) + if(CUDA_VERSION VERSION_EQUAL "3.0") + # This only existed in the 3.0 version of the CUDA toolkit + unset(CUDA_CUDARTEMU_LIBRARY CACHE) + endif() unset(CUDA_CUDA_LIBRARY CACHE) unset(CUDA_cublas_LIBRARY CACHE) unset(CUDA_cublasemu_LIBRARY CACHE) @@ -484,6 +488,10 @@ if(CUDA_NVCC_EXECUTABLE AND NOT CUDA_VERSION) string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\2" CUDA_VERSION_MINOR ${NVCC_OUT}) set(CUDA_VERSION "${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR}" CACHE STRING "Version of CUDA as computed from nvcc.") mark_as_advanced(CUDA_VERSION) +else() + # Need to set these based off of the cached value + string(REGEX REPLACE "([0-9]+)\\.([0-9]+).*" "\\1" CUDA_VERSION_MAJOR "${CUDA_VERSION}") + string(REGEX REPLACE "([0-9]+)\\.([0-9]+).*" "\\2" CUDA_VERSION_MINOR "${CUDA_VERSION}") endif() # Always set this convenience variable @@ -545,11 +553,28 @@ endmacro() # CUDA_LIBRARIES find_library_local_first(CUDA_CUDART_LIBRARY cudart "\"cudart\" library") -set(CUDA_LIBRARIES ${CUDA_CUDART_LIBRARY}) +if(CUDA_VERSION VERSION_EQUAL "3.0") + # The cudartemu library only existed for the 3.0 version of CUDA. + find_library_local_first(CUDA_CUDARTEMU_LIBRARY cudartemu "\"cudartemu\" library") + mark_as_advanced( + CUDA_CUDARTEMU_LIBRARY + ) +endif() +# If we are using emulation mode and we found the cudartemu library then use +# that one instead of cudart. +if(CUDA_BUILD_EMULATION AND CUDA_CUDARTEMU_LIBRARY) + set(CUDA_LIBRARIES ${CUDA_CUDARTEMU_LIBRARY}) +else() + set(CUDA_LIBRARIES ${CUDA_CUDART_LIBRARY}) +endif() if(APPLE) # We need to add the path to cudart to the linker using rpath, since the # library name for the cuda libraries is prepended with @rpath. - get_filename_component(_cuda_path_to_cudart "${CUDA_CUDART_LIBRARY}" PATH) + if(CUDA_BUILD_EMULATION AND CUDA_CUDARTEMU_LIBRARY) + get_filename_component(_cuda_path_to_cudart "${CUDA_CUDARTEMU_LIBRARY}" PATH) + else() + get_filename_component(_cuda_path_to_cudart "${CUDA_CUDART_LIBRARY}" PATH) + endif() if(_cuda_path_to_cudart) list(APPEND CUDA_LIBRARIES -Wl,-rpath "-Wl,${_cuda_path_to_cudart}") endif() diff --git a/cmake/FindLibXml2.cmake b/cmake/FindLibXml2.cmake index c5efc721b0..67db32122b 100644 --- a/cmake/FindLibXml2.cmake +++ b/cmake/FindLibXml2.cmake @@ -1,4 +1,4 @@ -# - Try to find LibXml2 +# - Try to find the LibXml2 xml processing library # Once done this will define # # LIBXML2_FOUND - System has LibXml2 @@ -7,26 +7,27 @@ # LIBXML2_DEFINITIONS - Compiler switches required for using LibXml2 # LIBXML2_XMLLINT_EXECUTABLE - The XML checking tool xmllint coming with LibXml2 -# Copyright (c) 2006, Alexander Neundorf, +#============================================================================= +# Copyright 2006-2009 Kitware, Inc. +# Copyright 2006 Alexander Neundorf # -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - - -IF (LIBXML2_INCLUDE_DIR AND LIBXML2_LIBRARIES) - # in cache already - SET(LibXml2_FIND_QUIETLY TRUE) -ENDIF (LIBXML2_INCLUDE_DIR AND LIBXML2_LIBRARIES) - -IF (NOT WIN32) - # use pkg-config to get the directories and then use these values - # in the FIND_PATH() and FIND_LIBRARY() calls - FIND_PACKAGE(PkgConfig) - PKG_CHECK_MODULES(PC_LIBXML libxml-2.0) - SET(LIBXML2_DEFINITIONS ${PC_LIBXML_CFLAGS_OTHER}) -ENDIF (NOT WIN32) - -FIND_PATH(LIBXML2_INCLUDE_DIR libxml/xpath.h +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distributed this file outside of CMake, substitute the full +# License text for the above reference.) + +# use pkg-config to get the directories and then use these values +# in the FIND_PATH() and FIND_LIBRARY() calls +FIND_PACKAGE(PkgConfig) +PKG_CHECK_MODULES(PC_LIBXML libxml-2.0 QUIET) +SET(LIBXML2_DEFINITIONS ${PC_LIBXML_CFLAGS_OTHER}) + +FIND_PATH(LIBXML2_INCLUDE_DIR NAMES libxml/xpath.h HINTS ${PC_LIBXML_INCLUDEDIR} ${PC_LIBXML_INCLUDE_DIRS} @@ -43,10 +44,9 @@ FIND_PROGRAM(LIBXML2_XMLLINT_EXECUTABLE xmllint) # for backwards compat. with KDE 4.0.x: SET(XMLLINT_EXECUTABLE "${LIBXML2_XMLLINT_EXECUTABLE}") -INCLUDE(FindPackageHandleStandardArgs) - # handle the QUIETLY and REQUIRED arguments and set LIBXML2_FOUND to TRUE if # all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR) MARK_AS_ADVANCED(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARIES LIBXML2_XMLLINT_EXECUTABLE) diff --git a/cmake/FindMPI.cmake b/cmake/FindMPI.cmake index 03e95ef714..481b0e994d 100644 --- a/cmake/FindMPI.cmake +++ b/cmake/FindMPI.cmake @@ -1,5 +1,5 @@ # - Message Passing Interface (MPI) module. -# +# # The Message Passing Interface (MPI) is a library used to write # high-performance parallel applications that use message passing, and # is typically deployed on a cluster. MPI is a standard interface @@ -35,7 +35,7 @@ # # If no compiler driver is found or the compiler driver is not # recognized, this module will then search for common include paths -# and library names to try to detect MPI. +# and library names to try to detect MPI. # # If CMake initially finds a different MPI than was intended, and you # want to use the MPI compiler auto-detection for a different MPI @@ -49,24 +49,81 @@ # ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} PROCS ${MPIEXEC_PREFLAGS} EXECUTABLE # ${MPIEXEC_POSTFLAGS} ARGS # where PROCS is the number of processors on which to execute the program, -# EXECUTABLE is the MPI program, and ARGS are the arguments to pass to the +# EXECUTABLE is the MPI program, and ARGS are the arguments to pass to the # MPI program. -# Try to find the MPI driver program -find_program(MPI_COMPILER - NAMES mpic++ mpicxx mpiCC mpicc - DOC "MPI compiler. Used only to detect MPI compilation flags.") -mark_as_advanced(MPI_COMPILER) +#============================================================================= +# Copyright 2001-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distributed this file outside of CMake, substitute the full +# License text for the above reference.) +# This module is maintained by David Partyka . + +# A set of directories to search through in addition to the standard system paths +# that find_program will search through. +# Microsoft HPC SDK is automatically added to the system path +# Argonne National Labs MPICH2 sets a registry key that we can use. + +set(_MPI_PACKAGE_DIR + mpi + mpich + openmpi + lib/mpi + lib/mpich + lib/openmpi + "MPICH/SDK" + "Microsoft Compute Cluster Pack" + ) + +set(_MPI_PREFIX_PATH) +if(WIN32) + list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]/..") + list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH2;Path]") +endif() + +foreach(SystemPrefixDir ${CMAKE_SYSTEM_PREFIX_PATH}) + foreach(MpiPackageDir ${_MPI_PREFIX_PATH}) + if(EXISTS ${SystemPrefixDir}/${MpiPackageDir}) + list(APPEND _MPI_PREFIX_PATH "${SystemPrefixDir}/${MpiPackageDir}") + endif() + endforeach(MpiPackageDir) +endforeach(SystemPrefixDir) + +# Most mpi distros have some form of mpiexec which gives us something we can reliably look for. find_program(MPIEXEC NAMES mpiexec mpirun lamexec - DOC "Executable for running MPI programs.") + PATHS ${_MPI_PREFIX_PATH} + PATH_SUFFIXES bin + DOC "Executable for running MPI programs." + ) + +# call get_filename_component twice to remove mpiexec and the directory it exists in (typically bin). +# This gives us a fairly reliable base directory to search for /bin /lib and /include from. +get_filename_component(_MPI_BASE_DIR "${MPIEXEC}" PATH) +get_filename_component(_MPI_BASE_DIR "${_MPI_BASE_DIR}" PATH) + +# If there is an mpi compiler find it and interogate (farther below) it for the include +# and lib dirs otherwise we will continue to search from ${_MPI_BASE_DIR}. +find_program(MPI_COMPILER + NAMES mpic++ mpicxx mpiCC mpicc + HINTS "${_MPI_BASE_DIR}" + PATH_SUFFIXES bin + DOC "MPI compiler. Used only to detect MPI compilation flags.") +mark_as_advanced(MPI_COMPILER) set(MPIEXEC_NUMPROC_FLAG "-np" CACHE STRING "Flag used by MPI to specify the number of processes for MPIEXEC; the next option will be the number of processes.") set(MPIEXEC_PREFLAGS "" CACHE STRING "These flags will be directly before the executable that is being run by MPIEXEC.") set(MPIEXEC_POSTFLAGS "" CACHE STRING "These flags will come after all flags given to MPIEXEC.") set(MPIEXEC_MAX_NUMPROCS "2" CACHE STRING "Maximum number of processors available to run MPI applications.") -mark_as_advanced(MPIEXEC MPIEXEC_NUMPROC_FLAG MPIEXEC_PREFLAGS +mark_as_advanced(MPIEXEC MPIEXEC_NUMPROC_FLAG MPIEXEC_PREFLAGS MPIEXEC_POSTFLAGS MPIEXEC_MAX_NUMPROCS) if (MPI_INCLUDE_PATH AND MPI_LIBRARY) @@ -76,15 +133,16 @@ elseif (MPI_COMPILER) # Check whether the -showme:compile option works. This indicates # that we have either Open MPI or a newer version of LAM-MPI, and # implies that -showme:link will also work. - exec_program(${MPI_COMPILER} - ARGS -showme:compile + # Note that Windows distros do not have an mpi compiler to interogate. + exec_program(${MPI_COMPILER} + ARGS -showme:compile OUTPUT_VARIABLE MPI_COMPILE_CMDLINE RETURN_VALUE MPI_COMPILER_RETURN) if (MPI_COMPILER_RETURN EQUAL 0) # If we appear to have -showme:compile, then we should also have # -showme:link. Try it. - exec_program(${MPI_COMPILER} + exec_program(${MPI_COMPILER} ARGS -showme:link OUTPUT_VARIABLE MPI_LINK_CMDLINE RETURN_VALUE MPI_COMPILER_RETURN) @@ -98,21 +156,21 @@ elseif (MPI_COMPILER) # Do nothing: we have our command lines now else (MPI_COMPILER_RETURN EQUAL 0) # Older versions of LAM-MPI have "-showme". Try it. - exec_program(${MPI_COMPILER} + exec_program(${MPI_COMPILER} ARGS -showme OUTPUT_VARIABLE MPI_COMPILE_CMDLINE RETURN_VALUE MPI_COMPILER_RETURN) - endif (MPI_COMPILER_RETURN EQUAL 0) + endif (MPI_COMPILER_RETURN EQUAL 0) if (MPI_COMPILER_RETURN EQUAL 0) # Do nothing: we have our command lines now else (MPI_COMPILER_RETURN EQUAL 0) # MPICH uses "-show". Try it. - exec_program(${MPI_COMPILER} + exec_program(${MPI_COMPILER} ARGS -show OUTPUT_VARIABLE MPI_COMPILE_CMDLINE RETURN_VALUE MPI_COMPILER_RETURN) - endif (MPI_COMPILER_RETURN EQUAL 0) + endif (MPI_COMPILER_RETURN EQUAL 0) if (MPI_COMPILER_RETURN EQUAL 0) # We have our command lines, but we might need to copy @@ -148,12 +206,12 @@ elseif (MPI_COMPILE_CMDLINE) string(REGEX REPLACE "//" "/" IPATH ${IPATH}) list(APPEND MPI_INCLUDE_PATH_WORK ${IPATH}) endforeach(IPATH) - + if (NOT MPI_INCLUDE_PATH_WORK) if (MPI_COMPILER_MAY_HAVE_INCLIBDIRS) # The compile command line didn't have any include paths on it, # but we may have -showme:incdirs. Use it. - exec_program(${MPI_COMPILER} + exec_program(${MPI_COMPILER} ARGS -showme:incdirs OUTPUT_VARIABLE MPI_INCLUDE_PATH_WORK RETURN_VALUE MPI_COMPILER_RETURN) @@ -164,7 +222,10 @@ elseif (MPI_COMPILE_CMDLINE) if (NOT MPI_INCLUDE_PATH_WORK) # If all else fails, just search for mpi.h in the normal include # paths. - find_path(MPI_INCLUDE_PATH mpi.h) + find_path(MPI_INCLUDE_PATH mpi.h + HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH} + PATH_SUFFIXES include + ) set(MPI_INCLUDE_PATH_WORK ${MPI_INCLUDE_PATH}) endif (NOT MPI_INCLUDE_PATH_WORK) @@ -181,7 +242,7 @@ elseif (MPI_COMPILE_CMDLINE) if (MPI_COMPILER_MAY_HAVE_INCLIBDIRS) # The compile command line didn't have any linking paths on it, # but we may have -showme:libdirs. Use it. - exec_program(${MPI_COMPILER} + exec_program(${MPI_COMPILER} ARGS -showme:libdirs OUTPUT_VARIABLE MPI_LINK_PATH RETURN_VALUE MPI_COMPILER_RETURN) @@ -242,39 +303,29 @@ elseif (MPI_COMPILE_CMDLINE) set(MPI_INCLUDE_PATH ${MPI_INCLUDE_PATH_WORK} CACHE STRING "MPI include path" FORCE) set(MPI_LINK_FLAGS ${MPI_LINK_FLAGS_WORK} CACHE STRING "MPI linking flags" FORCE) else (MPI_COMPILE_CMDLINE) - find_path(MPI_INCLUDE_PATH mpi.h - /usr/local/include - /usr/include - /usr/include/mpi - /usr/local/mpi/include - "C:/Program Files/MPICH/SDK/Include" - "$ENV{SystemDrive}/Program Files/MPICH2/include" - "$ENV{SystemDrive}/Program Files/Microsoft Compute Cluster Pack/Include" +# No MPI compiler to interogate so attempt to find everything with find functions. + find_path(MPI_INCLUDE_PATH mpi.h + HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH} + PATH_SUFFIXES include ) - + # Decide between 32-bit and 64-bit libraries for Microsoft's MPI - if (CMAKE_CL_64) + if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) set(MS_MPI_ARCH_DIR amd64) - else (CMAKE_CL_64) + else() set(MS_MPI_ARCH_DIR i386) - endif (CMAKE_CL_64) - - find_library(MPI_LIBRARY + endif() + + find_library(MPI_LIBRARY NAMES mpi mpich msmpi - PATHS /usr/lib /usr/local/lib /usr/local/mpi/lib - "C:/Program Files/MPICH/SDK/Lib" - "$ENV{SystemDrive}/Program Files/MPICH/SDK/Lib" - "$ENV{SystemDrive}/Program Files/Microsoft Compute Cluster Pack/Lib/${MS_MPI_ARCH_DIR}" + HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH} + PATH_SUFFIXES lib lib/${MS_MPI_ARCH_DIR} Lib Lib/${MS_MPI_ARCH_DIR} ) - find_library(MPI_LIBRARY - NAMES mpich2 - PATHS - "$ENV{SystemDrive}/Program Files/MPICH2/Lib") - find_library(MPI_EXTRA_LIBRARY + find_library(MPI_EXTRA_LIBRARY NAMES mpi++ - PATHS /usr/lib /usr/local/lib /usr/local/mpi/lib - "C:/Program Files/MPICH/SDK/Lib" + HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH} + PATH_SUFFIXES lib DOC "Extra MPI libraries to link against.") set(MPI_COMPILE_FLAGS "" CACHE STRING "MPI compilation flags") @@ -287,7 +338,7 @@ if("${MPI_LIBRARY}" MATCHES "mpich.rts") set(MPI_LIBRARY ${MPI_LIBRARY} msglayer.rts devices.rts rts.rts devices.rts) endif("${MPI_LIBRARY}" MATCHES "mpich.rts") -# Set up extra variables to conform to +# Set up extra variables to conform to if (MPI_EXTRA_LIBRARY) set(MPI_LIBRARIES ${MPI_LIBRARY} ${MPI_EXTRA_LIBRARY}) else (MPI_EXTRA_LIBRARY) @@ -301,8 +352,13 @@ else (MPI_INCLUDE_PATH AND MPI_LIBRARY) endif (MPI_INCLUDE_PATH AND MPI_LIBRARY) include(FindPackageHandleStandardArgs) -# handle the QUIETLY and REQUIRED arguments +# handle the QUIETLY and REQUIRED arguments find_package_handle_standard_args(MPI DEFAULT_MSG MPI_LIBRARY MPI_INCLUDE_PATH) -mark_as_advanced(MPI_INCLUDE_PATH MPI_COMPILE_FLAGS MPI_LINK_FLAGS MPI_LIBRARY +mark_as_advanced(MPI_INCLUDE_PATH MPI_COMPILE_FLAGS MPI_LINK_FLAGS MPI_LIBRARY MPI_EXTRA_LIBRARY) + +# unset to cleanup namespace +unset(_MPI_PACKAGE_DIR) +unset(_MPI_PREFIX_PATH) +unset(_MPI_BASE_DIR) -- 2.11.4.GIT