Reworked FindFFTW.cmake
authorChristoph Junghans <junghans@votca.org>
Tue, 3 Apr 2012 17:59:58 +0000 (11:59 -0600)
committerChristoph Junghans <junghans@votca.org>
Thu, 12 Apr 2012 15:57:17 +0000 (09:57 -0600)
* make user input FFTW_{LIBRARY|INCLUDE_DIR} work and advanced
* ade more documentation
* reconsider test if failed in the last run
* improve error messages to the user
* check if fftw is compiled with sse support
* fixed detection on Cray

Change-Id: I0b7d440d372da7cf897ca956ccd882e21b109591

CMakeLists.txt
cmake/FindFFTW.cmake

index 5cde4d682de3a56d44cf3abf90d5b000ebe6cc8f..a9fef964bab3cf7be98073550c4c66a95572cc03 100644 (file)
@@ -692,6 +692,10 @@ if(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
 
     set(GMX_FFT_FFTW3 1)
 
+    if (${GMX_ACCELERATION} STREQUAL "SSE" AND NOT FFTW_HAVE_SSE)
+      message(WARNING "The fftw library found is compiled without SSE support, which makes it slow. Consider recompiling it or contact your admin")
+    endif (${GMX_ACCELERATION} STREQUAL "SSE" AND NOT FFTW_HAVE_SSE)
+
 elseif(${GMX_FFT_LIBRARY} STREQUAL "MKL")
 #    MESSAGE(STATUS "Using external FFT library - Intel MKL")
     find_package(MKL REQUIRED)
index 288963c5631dd21e81d114f7af122bb9becf05fe..f1476adbf1e30015002ec8e61c28102d9ebf48a1 100644 (file)
@@ -4,6 +4,7 @@
 #  FFTW_INCLUDE_DIRS - where to find FFTW headers
 #  FFTW_LIBRARIES    - List of libraries when using FFTW.
 #  FFTW_PKG          - The name of the pkg-config package needed
+#  FFTW_HAVE_SSE     - True if FFTW was build with SSE support
 #  FFTW_FOUND        - True if FFTW was found
 #
 #  This file is part of Gromacs        Copyright (c) 2012
@@ -37,36 +38,65 @@ else()
   message(FATAL_ERROR "We do not support finding ${FFTW_FIND_COMPONENTS}, go and implement it ;-)")
 endif()
 
-if(NOT __pkg_config_checked_PC_FFTW)
-  pkg_check_modules(PC_FFTW "${FFTW_PKG}")
-endif(NOT __pkg_config_checked_PC_FFTW)
+if(NOT __pkg_config_checked_PC_FFTW_${FFTW_PKG})
+  pkg_check_modules(PC_FFTW_${FFTW_PKG} "${FFTW_PKG}")
+endif(NOT __pkg_config_checked_PC_FFTW_${FFTW_PKG})
 
-find_path(FFTW_INCLUDE_DIR_${FFTW_PKG} "${FFTW_HEADER}" HINTS ${PC_FFTW_INCLUDE_DIRS})
-find_library(FFTW_LIBRARY_${FFTW_PKG} NAMES "${FFTW_PKG}" HINTS ${PC_FFTW_LIBRARY_DIRS} )
+if(FFTW_LIBRARY)
+  set(FFTW_LIBRARY_${FFTW_PKG} "${FFTW_LIBRARY}" CACHE INTERNAL "Path to ${FFTW_PKG} library" FORCE)
+endif(FFTW_LIBRARY)
 
-#make _${FFTW_PKG} variables INTERNAL to avoid confusion
-set(FFTW_LIBRARY_${FFTW_PKG} ${FFTW_LIBRARY_${FFTW_PKG}} CACHE INTERNAL "Path to library ${FFTW_PKG}")
-set(FFTW_INCLUDE_DIR_${FFTW_PKG} ${FFTW_INCLUDE_DIR_${FFTW_PKG}} CACHE INTERNAL "Path to ${FFTW_HEADER}")
+if(FFTW_INCLUDE_DIR)
+  set(FFTW_INCLUDE_DIR_${FFTW_PKG} "${FFTW_INCLUDE_DIR}" CACHE INTERNAL "Path to ${FFTW_HEADER}" FORCE)
+endif(FFTW_INCLUDE_DIR)
 
-set(FFTW_LIBRARY ${FFTW_LIBRARY_${FFTW_PKG}} CACHE STRING "Path to library ${FFTW_PKG}")
-set(FFTW_INCLUDE_DIR ${FFTW_INCLUDE_DIR_${FFTW_PKG}} CACHE STRING "Path to ${FFTW_HEADER}")
+#we use _${FFTW_PKG} variables to have different cache entries for fftw3 and ffw3f
+find_path(FFTW_INCLUDE_DIR_${FFTW_PKG} "${FFTW_HEADER}" HINTS ${PC_FFTW_${FFTW_PKG}_INCLUDE_DIRS})
+find_library(FFTW_LIBRARY_${FFTW_PKG} NAMES "${FFTW_PKG}" HINTS ${PC_FFTW_${FFTW_PKG}_LIBRARY_DIRS})
 
-set(FFTW_LIBRARIES ${FFTW_LIBRARY} )
-set(FFTW_INCLUDE_DIRS ${FFTW_INCLUDE_DIR} )
+#make _${FFTW_PKG} variables INTERNAL to avoid confusion in cmake-gui
+set(FFTW_LIBRARY_${FFTW_PKG} ${FFTW_LIBRARY_${FFTW_PKG}} CACHE INTERNAL "Path to ${FFTW_PKG} library" FORCE)
+set(FFTW_INCLUDE_DIR_${FFTW_PKG} ${FFTW_INCLUDE_DIR_${FFTW_PKG}} CACHE INTERNAL "Path to ${FFTW_HEADER}" FORCE)
 
-include(FindPackageHandleStandardArgs)
-# handle the QUIETLY and REQUIRED arguments and set FFTW_FOUND to TRUE
-# if all listed variables are TRUE
+set(FFTW_LIBRARY "${FFTW_LIBRARY_${FFTW_PKG}}" CACHE FILEPATH "Path to ${FFTW_PKG} library" FORCE)
+set(FFTW_INCLUDE_DIR "${FFTW_INCLUDE_DIR_${FFTW_PKG}}" CACHE DIRECTORY "Path to ${FFTW_HEADER}" FORCE)
 
-find_package_handle_standard_args(FFTW DEFAULT_MSG FFTW_LIBRARY FFTW_INCLUDE_DIR )
+# set default find_package outcome variables
+set(FFTW_LIBRARIES "${FFTW_LIBRARY_${FFTW_PKG}}")
+set(FFTW_INCLUDE_DIRS "${FFTW_INCLUDE_DIR_${FFTW_PKG}}")
 
-if (FFTW_FOUND AND HAVE_LIBM)
+set(FFTW_FOUND FALSE)
+if (FFTW_LIBRARY_${FFTW_PKG} AND FFTW_INCLUDE_DIR_${FFTW_PKG})
+  set(FFTW_FOUND TRUE)
+elseif (NOT FFTW_LIBRARY_${FFTW_PKG})
+  message("Could not find ${FFTW_PKG} library named lib${FFTW_PKG}, please specify its location in FFTW_LIBRARY by hand (e.g. -DFFTW_LIBRARY='/path/to/lib${FFTW_PKG}.so')")
+elseif (NOT FFTW_INCLUDE_DIR_${FFTW_PKG})
+  message("Could not the ${FFTW_PKG} header ${FFTW_HEADER}, please specify its path in FFTW_INCLUDE_DIR by hand (e.g. -DFFTW_INCLUDE_DIR='/path/to/include')")
+endif()
+
+set(FFTW_HAVE_SSE FALSE CACHE BOOL "If ${FFTW_PKG} was built with SSE support")
+if (FFTW_FOUND AND HAVE_LIBM AND NOT "${FFTW_LIBRARY_PREVIOUS}" STREQUAL "${FFTW_LIBRARY}")
+  #The user could specify trash in FFTW_LIBRARY, so test if we can link it
   include(CheckLibraryExists)
   #adding MATH_LIBRARIES here to allow static libs, this does not harm us as we are anyway using it
-  check_library_exists("${FFTW_LIBRARIES};m" "${FFTW_FUNCTION}" "" FOUND_FFTW_PLAN)
-  if(NOT FOUND_FFTW_PLAN)
-    message(FATAL_ERROR "Could not find ${FFTW_FUNCTION} in ${FFTW_LIBRARY}, take a look at the error message in ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log to find out what was going wrong. If you are using a static lib (.a) make sure you have specified all dependencies of ${FFTW_PKG} in FFTW_LIBRARY by hand (e.g. -DFFTW_LIBRARY='/path/to/lib${FFTW_PKG}.so;/path/to/libm.so') !")
-  endif(NOT FOUND_FFTW_PLAN)
-endif (FFTW_FOUND AND HAVE_LIBM)
+  set(CMAKE_REQUIRED_LIBRARIES m)
+  unset(FOUND_FFTW_PLAN_${FFTW_PKG} CACHE)
+  check_library_exists("${FFTW_LIBRARIES}" "${FFTW_FUNCTION}" "" FOUND_FFTW_PLAN_${FFTW_PKG})
+  if(NOT FOUND_FFTW_PLAN_${FFTW_PKG})
+    message(FATAL_ERROR "Could not find ${FFTW_FUNCTION} in ${FFTW_LIBRARY_${FFTW_PKG}}, take a look at the error message in ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log to find out what went wrong. If you are using a static lib (.a) make sure you have specified all dependencies of ${FFTW_PKG} in FFTW_LIBRARY by hand (e.g. -DFFTW_LIBRARY='/path/to/lib${FFTW_PKG}.so;/path/to/libm.so') !")
+  endif(NOT FOUND_FFTW_PLAN_${FFTW_PKG})
+  #in 3.3 sse function name has changed
+  foreach(SSE_FCT fftwf_have_simd_sse2;fftw_have_simd_sse2;fftwf_have_sse;fftw_have_sse2)
+    unset(FFTW_HAVE_${SSE_FCT}_${FFTW_PKG} CACHE)
+    check_library_exists("${FFTW_LIBRARIES}" "${SSE_FCT}" "" FFTW_HAVE_${SSE_FCT}_${FFTW_PKG})
+    if(FFTW_HAVE_${SSE_FCT}_${FFTW_PKG})
+      set(FFTW_HAVE_SSE_${FFTW_PKG} "${FFTW_HAVE_${SSE_FCT}_${FFTW_PKG}}")
+      break()
+    endif(FFTW_HAVE_${SSE_FCT}_${FFTW_PKG})
+  endforeach()
+  set(FFTW_HAVE_SSE "${FFTW_HAVE_SSE_${FFTW_PKG}}" CACHE BOOL "If ${FFTW_PKG} was built with SSE support" FORCE)
+  set(CMAKE_REQUIRED_LIBRARIES)
+  set(FFTW_LIBRARY_PREVIOUS "${FFTW_LIBRARY}" CACHE INTERNAL "Value of FFTW_LIBRARY when executing the linking check that last time" FORCE)
+endif (FFTW_FOUND AND HAVE_LIBM AND NOT "${FFTW_LIBRARY_PREVIOUS}" STREQUAL "${FFTW_LIBRARY}")
 
-mark_as_advanced(FFTW_INCLUDE_DIR FFTW_LIBRARY )
+mark_as_advanced(FFTW_INCLUDE_DIR FFTW_LIBRARY FFTW_HAVE_SSE)