Fix FindFFTW behaviour
authorMark Abraham <mark.j.abraham@gmail.com>
Tue, 22 Sep 2015 14:46:08 +0000 (16:46 +0200)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Sat, 3 Oct 2015 18:10:25 +0000 (20:10 +0200)
FFTW 3.3.5 with --enable-avx* will enable any useful 128-bit
SIMD flavours by default. (See Erik's 579cec9a6 in their repo.) Our
detection code will observe this, and will be silent.

With earlier FFTW, if we're doing a GROMACS AVX build, and we have
FFTW SIMD, and not SSE(2) SIMD, then we want to warn the user to
reconfigure FFTW to add SSE support. Made this behaviour correct, and
minimized the necessary infrastructure for it.

Added detection support for some other SIMD-support symbols that
are present in the FFTW repo for upcoming hardware.

Fixes #1809

Change-Id: If586250895664581316505a5595da7442e789f8d

cmake/FindFFTW.cmake
cmake/gmxManageFFTLibraries.cmake

index dbe8f92c4bcc731bb6ef25f3f43432c375a1cb56..9edfc2c309502c217a6a618875d4339e83322379 100644 (file)
@@ -39,7 +39,8 @@
 #  ${FFTW}_LIBRARIES    - List of libraries when using FFTW.
 #  ${FFTW}_PKG          - The name of the pkg-config package needed
 #  ${FFTW}_HAVE_SIMD    - True if FFTW was built with SIMD support
-#  ${FFTW}_HAVE_AVX     - True if FFTW was built with AVX support
+#  ${FFTW}_HAVE_SSE     - True if FFTW was built with SSE support
+#  ${FFTW}_HAVE_SSE2    - True if FFTW was built with SSE2 support
 #  ${FFTW}_FOUND        - True if FFTW was found
 #  where ${FFTW} is FFTW or FFTWF
 
@@ -101,64 +102,55 @@ if (${FFTW}_FOUND)
   endif()
 
   # Check for FFTW3 compiled with --enable-sse
-  foreach(SSE_FUNCTION ${${FFTW}_FUNCTION_PREFIX}_have_simd_sse)
+  foreach(SSE_FUNCTION ${${FFTW}_FUNCTION_PREFIX}_have_simd_sse ${${FFTW}_FUNCTION_PREFIX}_have_sse)
     if (FFTW_LIBRARY_CHANGED)
       unset(${FFTW}_HAVE_${SSE_FUNCTION} CACHE)
     endif()
     check_library_exists("${${FFTW}_LIBRARIES}" "${SSE_FUNCTION}" "" ${FFTW}_HAVE_${SSE_FUNCTION})
     if(${FFTW}_HAVE_${SSE_FUNCTION})
       set(${FFTW}_HAVE_SSE TRUE)
+      set(${FFTW}_HAVE_SIMD TRUE)
       break()
     endif()
   endforeach()
 
   # Check for FFTW3 compiled with --enable-sse2
-  foreach(SSE2_FUNCTION ${${FFTW}_FUNCTION_PREFIX}_have_simd_sse2)
+  foreach(SSE2_FUNCTION ${${FFTW}_FUNCTION_PREFIX}_have_simd_sse2 ${${FFTW}_FUNCTION_PREFIX}_have_sse2)
     if (FFTW_LIBRARY_CHANGED)
       unset(${FFTW}_HAVE_${SSE2_FUNCTION} CACHE)
     endif()
     check_library_exists("${${FFTW}_LIBRARIES}" "${SSE2_FUNCTION}" "" ${FFTW}_HAVE_${SSE2_FUNCTION})
     if(${FFTW}_HAVE_${SSE2_FUNCTION})
       set(${FFTW}_HAVE_SSE2 TRUE)
+      set(${FFTW}_HAVE_SIMD TRUE)
       break()
     endif()
   endforeach()
 
-  # Check for FFTW3 with 128-bit AVX compiled with --enable-avx
-  foreach(AVX_128_FUNCTION ${${FFTW}_FUNCTION_PREFIX}_have_simd_avx_128)
-    if (FFTW_LIBRARY_CHANGED)
-      unset(${FFTW}_HAVE_${AVX_128_FUNCTION} CACHE)
-    endif()
-    check_library_exists("${${FFTW}_LIBRARIES}" "${AVX_128_FUNCTION}" "" ${FFTW}_HAVE_${AVX_128_FUNCTION})
-    if(${FFTW}_HAVE_${AVX_128_FUNCTION})
-      set(${FFTW}_HAVE_AVX_128 TRUE)
-      break()
-    endif()
-  endforeach()
-
-  # Check for FFTW3 with 128-bit AVX2 compiled with --enable-avx2
-  foreach(AVX2_128_FUNCTION ${${FFTW}_FUNCTION_PREFIX}_have_simd_avx2_128)
-    if (FFTW_LIBRARY_CHANGED)
-      unset(${FFTW}_HAVE_${AVX2_128_FUNCTION} CACHE)
-    endif()
-    check_library_exists("${${FFTW}_LIBRARIES}" "${AVX2_128_FUNCTION}" "" ${FFTW}_HAVE_${AVX2_128_FUNCTION})
-    if(${FFTW}_HAVE_${AVX2_128_FUNCTION})
-      set(${FFTW}_HAVE_AVX2_128 TRUE)
-      break()
-    endif()
-  endforeach()
+  # Check for any other SIMD support in FFTW
+  if (NOT ${FFTW}_HAVE_SIMD)
+      foreach(SIMD_FCT
+              ${${FFTW}_FUNCTION_PREFIX}_have_simd_avx
+              ${${FFTW}_FUNCTION_PREFIX}_have_simd_avx2
+              ${${FFTW}_FUNCTION_PREFIX}_have_simd_avx2_128
+              ${${FFTW}_FUNCTION_PREFIX}_have_simd_avx512
+              ${${FFTW}_FUNCTION_PREFIX}_have_simd_avx_128_fma
+              ${${FFTW}_FUNCTION_PREFIX}_have_simd_altivec
+              ${${FFTW}_FUNCTION_PREFIX}_have_simd_neon
+              ${${FFTW}_FUNCTION_PREFIX}_have_simd_vsx
+              ${${FFTW}_FUNCTION_PREFIX}_have_simd_altivec
+              ${${FFTW}_FUNCTION_PREFIX}_have_altivec) # Name used before FFTW 3.3
+          if (FFTW_LIBRARY_CHANGED)
+              unset(${FFTW}_HAVE_${SIMD_FCT} CACHE)
+          endif()
+          check_library_exists("${${FFTW}_LIBRARIES}" "${SIMD_FCT}" "" ${FFTW}_HAVE_${SIMD_FCT})
+          if(${FFTW}_HAVE_${SIMD_FCT})
+              set(${FFTW}_HAVE_SIMD TRUE)
+              break()
+          endif()
+      endforeach()
+  endif()
 
-  #in 3.3 sse function name has changed
-  foreach(SIMD_FCT ${${FFTW}_FUNCTION_PREFIX}_have_simd_sse2;${${FFTW}_FUNCTION_PREFIX}_have_simd_avx;${${FFTW}_FUNCTION_PREFIX}_have_simd_altivec;${${FFTW}_FUNCTION_PREFIX}_have_simd_neon;${${FFTW}_FUNCTION_PREFIX}_have_sse2;${${FFTW}_FUNCTION_PREFIX}_have_sse;${${FFTW}_FUNCTION_PREFIX}_have_altivec)
-    if (FFTW_LIBRARY_CHANGED)
-      unset(${FFTW}_HAVE_${SIMD_FCT} CACHE)
-    endif()
-    check_library_exists("${${FFTW}_LIBRARIES}" "${SIMD_FCT}" "" ${FFTW}_HAVE_${SIMD_FCT})
-    if(${FFTW}_HAVE_${SIMD_FCT})
-      set(${FFTW}_HAVE_SIMD TRUE)
-      break()
-    endif()
-  endforeach()
   #Verify FFTW is compiled with fPIC (necessary for shared libraries)
   if (CMAKE_OBJDUMP AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND BUILD_SHARED_LIBS AND NOT CYGWIN)
       execute_process(COMMAND ${CMAKE_OBJDUMP} --reloc ${${FFTW}_LIBRARY} OUTPUT_VARIABLE ${FFTW}_OBJDUMP)
index f8fcc47b16660e8e3ef380ae99211fcda1e11a63..6f9c440b07fd4d5782646460e6a7dcbcb1ac78cd 100644 (file)
@@ -94,9 +94,13 @@ if(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
     if ((${GMX_SIMD} MATCHES "SSE" OR ${GMX_SIMD} MATCHES "AVX") AND NOT ${FFTW}_HAVE_SIMD)
       message(WARNING "The fftw library found is compiled without SIMD support, which makes it slow. Consider recompiling it or contact your admin")
     else()
-      if(${GMX_SIMD} MATCHES "AVX" AND NOT (${FFTW}_HAVE_SSE OR ${FFTW}_HAVE_SSE2 OR ${FFTW}_HAVE_AVX_128 OR ${FFTW}_HAVE_AVX2_128))
-        # If we end up here we have an AVX Gromacs build, and FFTW with SIMD, but no 128-bit SIMD, this means AVX is enabled for FFTW.
-        message(WARNING "The FFTW library was compiled with neither --enable-sse nor --enable-sse2; those would have enabled SSE(2) SIMD instructions. This will give suboptimal performance. You should (re)compile the FFTW library with both SSE2 and AVX instruction support (use both --enable-sse2 and --enable-avx). The FFTW library will determine at runtime which SIMD instruction set is fastest for different parts of the FFTs.")
+      if(${GMX_SIMD} MATCHES "AVX" AND NOT (${FFTW}_HAVE_SSE OR ${FFTW}_HAVE_SSE2))
+        # If we end up here we have an AVX Gromacs build, and FFTW
+        # with SIMD. FFTW 3.3.5 will have the behaviour that
+        # configuring with AVX support also adds SSE support, which is
+        # what we want. There is no good way to detect the FFTW
+        # version, however.
+        message(WARNING "The FFTW library was compiled with neither --enable-sse nor --enable-sse2; those would have enabled SSE(2) SIMD instructions. This will give suboptimal performance. You should (re)compile the FFTW library with both SSE2 and AVX instruction support (use both --enable-sse2 and --enable-avx). More recent versions of FFTW compile support for such narrower SIMD by default.")
         endif()
     endif()