From 1909f2ffe7d9d248e1f04da505c4c6bac0d7ee76 Mon Sep 17 00:00:00 2001 From: Mark Abraham Date: Tue, 22 Sep 2015 16:46:08 +0200 Subject: [PATCH] Fix FindFFTW behaviour 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 | 66 +++++++++++++++++---------------------- cmake/gmxManageFFTLibraries.cmake | 10 ++++-- 2 files changed, 36 insertions(+), 40 deletions(-) diff --git a/cmake/FindFFTW.cmake b/cmake/FindFFTW.cmake index dbe8f92c4b..9edfc2c309 100644 --- a/cmake/FindFFTW.cmake +++ b/cmake/FindFFTW.cmake @@ -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) diff --git a/cmake/gmxManageFFTLibraries.cmake b/cmake/gmxManageFFTLibraries.cmake index f8fcc47b16..6f9c440b07 100644 --- a/cmake/gmxManageFFTLibraries.cmake +++ b/cmake/gmxManageFFTLibraries.cmake @@ -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() -- 2.11.4.GIT