Merge release-4-6 into master
[alexxy/gromacs.git] / CMakeLists.txt
index 9dfbd26e6fd19e0023dc2a3e61eaad62f2308364..bc0f5e3941510093d264fc79fe707b8f886677d2 100644 (file)
@@ -62,8 +62,10 @@ endif()
 set(GMX_INSTALL_PREFIX "" CACHE STRING "Prefix gets appended to CMAKE_INSTALL_PREFIX. For cpack it sets the root folder of the archive.")
 mark_as_advanced(GMX_INSTALL_PREFIX)
 
+include(gmxBuildTypeReference)
+
 if(NOT CMAKE_BUILD_TYPE)
-    set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
+    set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel Reference." FORCE)
 endif(NOT CMAKE_BUILD_TYPE)
 
 enable_language(C)
@@ -76,7 +78,7 @@ set(CPACK_RESOURCE_FILE_WELCOME "${CMAKE_SOURCE_DIR}/admin/InstallWelcome.txt")
 # Its GPL/LGPL, so they do not have to agree to a license for mere usage, but some installers require this...
 set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
 set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/admin/InstallInfo.txt")
-set(CPACK_SOURCE_IGNORE_FILES ".isreposource;.git;.gitignore")
+set(CPACK_SOURCE_IGNORE_FILES "\\\\.isreposource$;\\\\.git/;\\\\.gitignore$")
 set(CPACK_PROJECT_CONFIG_FILE "${CMAKE_SOURCE_DIR}/CPackInit.cmake")
 SET(CPACK_SOURCE_INSTALLED_DIRECTORIES "${CMAKE_SOURCE_DIR};/;${CMAKE_BINARY_DIR}/man;man")
 set(CPACK_PACKAGE_CONTACT "gmx-users@gromacs.org")
@@ -159,6 +161,10 @@ option(GMX_POWERPC_INVSQRT "Use PowerPC hardware 1/sqrt" OFF)
 mark_as_advanced(GMX_POWERPC_INVSQRT)
 option(GMX_FAHCORE "Build a library with mdrun functionality" OFF)
 mark_as_advanced(GMX_FAHCORE)
+
+# decide on GPU settings based on user-settings and GPU/CUDA detection
+include(gmxManageGPU)
+
 option(GMX_OPENMM "Accelerated execution on GPUs through the OpenMM library (rerun cmake after changing to see relevant options)" OFF)
 
 include(gmxDetectAcceleration)
@@ -175,6 +181,8 @@ set(GMX_CPU_ACCELERATION "@GMX_SUGGESTED_CPU_ACCELERATION@"
 
 set(GMX_FFT_LIBRARY "fftw3" 
     CACHE STRING "FFT library choices: fftw3,mkl,fftpack[built-in]")
+option(GMX_BUILD_OWN_FFTW "Download and build FFTW 3 during the GROMACS build process, rather than fall back on the really slow fftpack." OFF)
+mark_as_advanced(GMX_BUILD_OWN_FFTW)
 option(GMX_DISABLE_FFTW_MEASURE 
        "Do not optimize FFTW setups (not needed with SSE)" OFF)
 mark_as_advanced(GMX_DISABLE_FFTW_MEASURE)
@@ -250,7 +258,7 @@ endif()
 include(gmxCFlags)
 gmx_c_flags()
 
-include(gmxGetCompilerVersion)
+include(gmxGetCompilerInfo)
 get_compiler_version()
 
 # gcc 4.4.x is buggy and crashes when compiling some files with O3 and OpenMP on.
@@ -259,6 +267,19 @@ get_compiler_version()
 include(gmxGCC44O3BugWorkaround)
 gmx_check_gcc44_bug_workaround_needed(GMX_USE_GCC44_BUG_WORKAROUND)
 
+# clang 3.0 is buggy for some unknown reason detected during adding
+# the SSE2 group kernels for GROMACS 4.6. If we ever work out what
+# that is, we should replace these tests with a compiler feature test,
+# update GROMACS Redmine task #1039 and perhaps report a clang bug.
+#
+# In the meantime, until we require CMake 2.8.10 we cannot rely on it to detect
+# the compiler version for us. So we need a manual check for clang 3.0.
+include(gmxDetectClang30)
+gmx_detect_clang_3_0(COMPILER_IS_CLANG_3_0)
+if(COMPILER_IS_CLANG_3_0)
+    message(FATAL_ERROR "Your compiler is clang version 3.0, which is known to be buggy for GROMACS. Use a different compiler.")
+endif()
+
 ########################################################################
 # Set up binary and library suffixing 
 ########################################################################
@@ -387,7 +408,6 @@ check_function_exists(fsync             HAVE_FSYNC)
 check_function_exists(_fileno           HAVE__FILENO)
 check_function_exists(fileno            HAVE_FILENO)
 check_function_exists(_commit           HAVE__COMMIT)
-check_function_exists(lstat             HAVE_LSTAT)
 check_function_exists(sigaction         HAVE_SIGACTION)
 check_function_exists(sysconf           HAVE_SYSCONF)
 check_function_exists(sched_setaffinity HAVE_SCHED_SETAFFINITY)
@@ -492,60 +512,11 @@ if(GMX_OPENMM)
     find_package(OpenMM) 
 endif(GMX_OPENMM)
 
-
 if(GMX_GPU)
-    if(GMX_DOUBLE)
-        message(WARNING "GPU acceleration is not available in double precision, disabled!")
-        set(GMX_GPU OFF CACHE BOOL "Enable GPU acceleration" FORCE)
-    endif()
+    # now that we have detected the dependencies, do the second configure pass
+    gmx_gpu_setup()
 endif(GMX_GPU)
 
-if(GMX_GPU)
-
-    # We support CUDA >=v3.2 on *nix, but <= v4.1 doesn't work with MSVC
-    if(MSVC)
-        find_package(CUDA 4.1)
-    else()
-        find_package(CUDA 3.2)
-    endif()
-
-    if (NOT EXISTS ${CUDA_TOOLKIT_ROOT_DIR})
-        message(FATAL_ERROR "
-    mdrun supports native GPU acceleration on NVIDIA hardware with compute
-    capability >=2.0. This requires the NVIDIA CUDA library, which was not
-    found; the location can be hinted by setting CUDA_TOOLKIT_ROOT_DIR.
-
-    CPU or GPU acceleration can be selected at runtime, but if you are
-    sure you can not make use of GPU acceleration, disable it by setting
-    the CMake variable GMX_GPU=OFF.")
-    endif()
-
-    if(NOT GMX_OPENMP)
-        message(WARNING "
-    In order to use GPU acceleration efficiently, mdrun requires OpenMP multithreding.
-    Without OpenMP only a single CPU core per GPU can be used which is suboptimal.
-    Note that with MPI multiple processes can be forced to use a single GPU, but this
-    typically inefficient.")
-    endif()
-
-    include(gmxManageNvccConfig)
-
-    # Check whether we can use atomic operations needed for polling wait for GPU
-    # (to avoid the cudaStreamSynchronize + ECC bug).
-    # With thread-MPI testing atomics has already been carried out, but without
-    # thread-MPI we need to invoke the atomics test independently.
-    if (NOT GMX_THREAD_MPI)
-        set(TEST_TMPI_ATOMICS_ONLY ON CACHE INTERNAL
-            "Test only the atomic operations of thread-MPI.")
-        include(ThreadMPI)
-    endif()
-
-endif()
-# Annoyingly enough, FindCUDA leaves a few variables behind as non-advanced.
-# We need to mark these advanced outside the conditional, otherwise, if the user
-# tuns GMX_GPU=OFF after a failed cmake pass, these variables will be left behind.
-mark_as_advanced(CUDA_BUILD_CUBIN CUDA_BUILD_EMULATION CUDA_SDK_ROOT_DIR CUDA_VERBOSE_BUILD)
-
 if(APPLE)
    find_library(ACCELERATE_FRAMEWORK Accelerate)
    list(APPEND GMX_EXTRA_LIBRARIES ${ACCELERATE_FRAMEWORK})
@@ -771,7 +742,7 @@ elseif(${GMX_CPU_ACCELERATION} STREQUAL "AVX_128_FMA" OR ${GMX_CPU_ACCELERATION}
         GMX_TEST_CFLAG(MSVC_AVX_CFLAG "/arch:AVX" GROMACS_C_FLAGS)
     endif (NOT GNU_AVX_CFLAG)
     if (NOT GNU_AVX_CFLAG AND NOT MSVC_AVX_CFLAG)
-        message(WARNING "No C AVX flag found. Consider a newer compiler, or disable AVX for much lower performance.")
+        message(WARNING "No C AVX flag found. Consider a newer compiler, or try SSE4.1 (lower performance).")
     endif (NOT GNU_AVX_CFLAG AND NOT MSVC_AVX_CFLAG)
 
     GMX_TEST_CXXFLAG(GNU_AVX_CXXFLAG "-mavx" GROMACS_CXX_FLAGS)
@@ -779,20 +750,24 @@ elseif(${GMX_CPU_ACCELERATION} STREQUAL "AVX_128_FMA" OR ${GMX_CPU_ACCELERATION}
        GMX_TEST_CXXFLAG(MSVC_AVX_CXXFLAG "/arch:AVX" GROMACS_CXX_FLAGS)
     endif (NOT GNU_AVX_CXXFLAG)
     if (NOT GNU_AVX_CXXFLAG AND NOT MSVC_AVX_CXXFLAG)
-       message(WARNING "No C++ AVX flag found. Consider a newer compiler, or disable AVX for much lower performance.")
+       message(WARNING "No C++ AVX flag found. Consider a newer compiler, or try SSE4.1 (lower performance).")
     endif (NOT GNU_AVX_CXXFLAG AND NOT MSVC_AVX_CXXFLAG)
 
     # Set the FMA4 flags (MSVC doesn't require any)
     if(${GMX_CPU_ACCELERATION} STREQUAL "AVX_128_FMA" AND NOT MSVC)
         GMX_TEST_CFLAG(GNU_FMA_CFLAG "-mfma4" GROMACS_C_FLAGS)
         if (NOT GNU_FMA_CFLAG)
-            message(WARNING "No C FMA4 flag found. Consider a newer compiler, or disable AVX_128_FMA for much lower performance.")
+            message(WARNING "No C FMA4 flag found. Consider a newer compiler, or try SSE4.1 (lower performance).")
         endif(NOT GNU_FMA_CFLAG)
+        GMX_TEST_CFLAG(GNU_XOP_CFLAG "-mxop" GROMACS_C_FLAGS)
+        # No big deal if we do not have xop, so no point yelling warnings about it.
         if (CMAKE_CXX_COMPILER_LOADED)
             GMX_TEST_CXXFLAG(GNU_FMA_CXXFLAG "-mfma4" GROMACS_CXX_FLAGS)
             if (NOT GNU_FMA_CXXFLAG)
-                message(WARNING "No C++ FMA flag found. Consider a newer compiler, or disable AVX_128_FMA for much lower performance.")
+                message(WARNING "No C++ FMA flag found. Consider a newer compiler, or try SSE4.1 (lower performance).")
             endif (NOT GNU_FMA_CXXFLAG)
+            GMX_TEST_CXXFLAG(GNU_XOP_CXXFLAG "-mxop" GROMACS_CXX_FLAGS)
+            # No big deal if we do not have xop, so no point yelling warnings about it.
         endif()
     endif()
 
@@ -934,23 +909,34 @@ set(PKG_FFT_LIBS "")
 if(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
     if(GMX_DOUBLE)
         set(FFTW fftw)
-    else(GMX_DOUBLE)
+    else()
         set(FFTW fftwf)
-    endif(GMX_DOUBLE)
-    find_package(FFTW COMPONENTS ${FFTW})
+    endif()
+
+    if(GMX_BUILD_OWN_FFTW)
+      add_subdirectory(src/contrib/fftw)
+    else()
+      find_package(FFTW COMPONENTS ${FFTW})
+    endif()
+
     string(TOUPPER "${FFTW}" FFTW)
     set(PKG_FFT "${${FFTW}_PKG}")
     include_directories(${${FFTW}_INCLUDE_DIRS})
     set(FFT_LIBRARIES ${${FFTW}_LIBRARIES})
     if(NOT ${FFTW}_FOUND)
-      MESSAGE(FATAL_ERROR "Cannot find FFTW3 (with correct precision - libfftw3f for single precision GROMACS or libfftw3 for double precision GROMACS). Fix it, choose another FFT library, or use the Gromacs built-in fftpack (slower)!")
-    endif(NOT ${FFTW}_FOUND)
+      MESSAGE(FATAL_ERROR "Cannot find FFTW 3 (with correct precision - libfftw3f for single-precision GROMACS or libfftw3 for double-precision GROMACS). Either choose the right precision, choose another FFT(W) library, enable the advanced option to let GROMACS build FFTW 3 for you, or use the really slow GROMACS built-in fftpack library.")
+    endif()
 
     set(GMX_FFT_FFTW3 1)
 
     if (NOT ${GMX_CPU_ACCELERATION} STREQUAL "NONE" 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")
-    endif (NOT ${GMX_CPU_ACCELERATION} STREQUAL "NONE" AND NOT ${FFTW}_HAVE_SIMD) 
+    endif()
+
+    if(NOT ${GMX_CPU_ACCELERATION} STREQUAL "NONE" AND ${FFTW}_HAVE_AVX)
+        # If we're not doing CPU acceleration, we don't care about FFTW performance on x86 either
+        message(WARNING "The FFTW library was compiled with --enable-avx to enable AVX SIMD instructions. That might sound like a good idea for your processor, but for FFTW versions up to 3.3.3, these are slower than the SSE/SSE2 SIMD instructions for the way GROMACS uses FFTs. Limitations in the way FFTW allows GROMACS to measure performance make it awkward for either GROMACS or FFTW to make the decision for you based on runtime performance. You should compile a different FFTW library with --enable-sse or --enable-sse2. If you have a more recent FFTW, you may like to compare the performance of GROMACS with FFTW libraries compiled with and without --enable-avx. However, the GROMACS developers do not really expect the FFTW AVX optimization to help, because the performance is limited by memory access, not computation.")
+    endif()
 
 elseif(${GMX_FFT_LIBRARY} STREQUAL "MKL")
 #    MESSAGE(STATUS "Using external FFT library - Intel MKL")
@@ -1095,31 +1081,14 @@ else()
     set(GMX_EXE_LINKER_FLAGS ${GMX_EXE_LINKER_FLAGS} ${OpenMP_LINKER_FLAGS})
     set(GMX_SHARED_LINKER_FLAGS ${GMX_SHARED_LINKER_FLAGS} ${OpenMP_SHARED_LINKER_FLAGS})
 endif()
+
 ######################################
 # Output compiler and CFLAGS used
 ######################################
-execute_process(COMMAND ${CMAKE_C_COMPILER} --version RESULT_VARIABLE TMP_RESULT OUTPUT_VARIABLE CC_VERSION ERROR_VARIABLE CC_VERSION)
-#try executing just the compiler command if that failed...
-if(TMP_RESULT)
-    execute_process(COMMAND ${CMAKE_C_COMPILER} RESULT_VARIABLE TMP_RESULT OUTPUT_VARIABLE CC_VERSION ERROR_VARIABLE CC_VERSION)
-endif()
-string(LENGTH "${CC_VERSION}" len)
-if(len)
-    string(REGEX MATCH "[^\n]+" CC_VERSION "${CC_VERSION}")
-endif()
-
-set(BUILD_COMPILER "@CMAKE_C_COMPILER@ @CMAKE_C_COMPILER_ID@ @CC_VERSION@")
-set(BUILD_CFLAGS "@CMAKE_C_FLAGS@")
-if(CMAKE_BUILD_TYPE STREQUAL "Debug")
-    set(BUILD_CFLAGS "@BUILD_CFLAGS@ @CMAKE_C_FLAGS_DEBUG@")
-elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
-    set(BUILD_CFLAGS "@BUILD_CFLAGS@ @CMAKE_C_FLAGS_RELEASE@")
-elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
-    set(BUILD_CFLAGS "@BUILD_CFLAGS@ @CMAKE_C_FLAGS_MINSIZEREL@")
-elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
-    set(BUILD_CFLAGS "@BUILD_CFLAGS@ @CMAKE_C_FLAGS_RELWITHDEBINFO@")
-endif()
-
+get_compiler_info(C BUILD_C_COMPILER BUILD_CFLAGS)
+if (CMAKE_CXX_COMPILER_LOADED)
+    get_compiler_info(CXX BUILD_CXX_COMPILER BUILD_CXXFLAGS)
+endif ()
 
 ########################################################################
 # Specify install locations and which subdirectories to process        #
@@ -1161,6 +1130,15 @@ add_subdirectory(share)
 add_subdirectory(src)
 add_subdirectory(scripts)
 
+# issue GPU acceleration/CUDA-related warning or error if GMX_GPU was set
+# Auto and NVIDIA GPUs were detected.
+if (CUDA_NOTFOUND_AUTO AND NOT GMX_GPU_DETECTION_DONE)
+    message(WARNING "${CUDA_NOTFOUND_MESSAGE}")
+    unset(CUDA_NOTFOUND_AUTO)
+    unset(CUDA_NOTFOUND_MESSAGE)
+endif()
+set(GMX_GPU_DETECTION_DONE TRUE CACHE INTERNAL "Whether GPU detection has already been done")
+
 #######################
 ## uninstall target
 #######################
@@ -1174,7 +1152,6 @@ ADD_CUSTOM_TARGET(uninstall
                   "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake")
 ###########################
 
-
 ########################################################################
 # Tests                                                                #
 ########################################################################