Add suggestions for updating binutils
authorMark Abraham <mark.j.abraham@gmail.com>
Mon, 25 Jan 2016 06:32:41 +0000 (07:32 +0100)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Wed, 27 Jan 2016 12:09:31 +0000 (13:09 +0100)
CentOS seems to ship with an old binutils, as well as compiler. Other
distros probably also do this. Install guide and cmake messages now
explicitly suggest updating such infrastructure.

Change-Id: Ieefd188e508d83d248a149d313190e7989e70557

cmake/gmxFindFlagsForSource.cmake
cmake/gmxManageSimd.cmake
docs/install-guide/index.rst

index d2533e72e40090e29bc336504bd7acb20f42c091..68673f69d0145d0c27c0ec2f2a48e48e342c027c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2013,2014, by the GROMACS development team, led by
+# Copyright (c) 2013,2014,2016, by the GROMACS development team, led by
 # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
 # and including many others, as listed in the AUTHORS file in the
 # top-level source directory and at http://www.gromacs.org.
 #                     The compiler is chosen based on the extension of this file
 # FLAGSVAR            Variable (string) to which we should add the correct flag
 # Args 5 through N    Multiple strings with optimization flags to test
+#
+# If a compile flag is found, but the project in check_c_source_compiles
+# fails to build, sets SUGGEST_BINUTILS_UPDATE in parent scope to suggest
+# that the calling code tell the user about this issue if needed.
 FUNCTION(GMX_FIND_CFLAG_FOR_SOURCE VARIABLE DESCRIPTION SOURCE CFLAGSVAR)
     IF(NOT DEFINED ${VARIABLE})
         # Insert a blank element last in the list (try without any flags too)
@@ -55,9 +59,13 @@ FUNCTION(GMX_FIND_CFLAG_FOR_SOURCE VARIABLE DESCRIPTION SOURCE CFLAGSVAR)
             check_c_compiler_flag("${_testflag}" ${COMPILE_FLAG_VARIABLE})
 
             if(${COMPILE_FLAG_VARIABLE})
-                # Check that we can compile SIMD source (this does not catch warnings)
+                # Check that we can compile SIMD source (this does not catch compiler warnings)
                 check_c_source_compiles("${SOURCE}" ${COMPILE_SIMD_VARIABLE})
-            endif(${COMPILE_FLAG_VARIABLE})
+                if(NOT ${COMPILE_SIMD_VARIABLE})
+                    message(STATUS "Compiler flag was valid, but executable did not build - perhaps update the binutils package")
+                    set(SUGGEST_BINUTILS_UPDATE 1 PARENT_SCOPE)
+                endif()
+            endif()
 
             if(${COMPILE_FLAG_VARIABLE} AND ${COMPILE_SIMD_VARIABLE})
                 set(${VARIABLE}_FLAG "${_testflag}" CACHE INTERNAL "${DESCRIPTION}")
@@ -82,6 +90,10 @@ ENDFUNCTION(GMX_FIND_CFLAG_FOR_SOURCE VARIABLE DESCRIPTION SOURCE CFLAGSVAR)
 #                     The compiler is chosen based on the extension of this file
 # FLAGSVAR            Variable (string) to which we should add the correct flag
 # Args 5 through N    Multiple strings with optimization flags to test
+#
+# If a compile flag is found, but the project in check_cxx_source_compiles
+# fails to build, sets SUGGEST_BINUTILS_UPDATE in parent scope to suggest
+# that the calling code tell the user about this issue if needed.
 FUNCTION(GMX_FIND_CXXFLAG_FOR_SOURCE VARIABLE DESCRIPTION SOURCE CXXFLAGSVAR)
 
     IF(NOT DEFINED ${VARIABLE})
@@ -99,9 +111,13 @@ FUNCTION(GMX_FIND_CXXFLAG_FOR_SOURCE VARIABLE DESCRIPTION SOURCE CXXFLAGSVAR)
             check_cxx_compiler_flag("${_testflag}" ${COMPILE_FLAG_VARIABLE})
 
             if(${COMPILE_FLAG_VARIABLE})
-                # Check that we can compile SIMD source (this does not catch warnings)
+                # Check that we can compile SIMD source (this does not catch compiler warnings)
                 check_cxx_source_compiles("${SOURCE}" ${COMPILE_SIMD_VARIABLE})
-            endif(${COMPILE_FLAG_VARIABLE})
+                if(NOT ${COMPILE_SIMD_VARIABLE})
+                    message(STATUS "Compiler flag was valid, but executable did not build - perhaps update the binutils package")
+                    set(SUGGEST_BINUTILS_UPDATE 1 PARENT_SCOPE)
+                endif()
+            endif()
 
             if(${COMPILE_FLAG_VARIABLE} AND ${COMPILE_SIMD_VARIABLE})
                 set(${VARIABLE}_FLAG "${_testflag}" CACHE INTERNAL "${DESCRIPTION}")
index 1b690289f88624b290f22c6d5678a7e603ba17b7..255ea7fc077b3b15e1c7957d2b0266f945a514d2 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
+# Copyright (c) 2012,2013,2014,2015,2016, by the GROMACS development team, led by
 # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
 # and including many others, as listed in the AUTHORS file in the
 # top-level source directory and at http://www.gromacs.org.
@@ -51,6 +51,21 @@ macro(gmx_use_clang_as_with_gnu_compilers_on_osx)
     endif()
 endmacro()
 
+# Issue a fatal error with an appropriate message, when the toolchain
+# was not able to compile code for SIMD support.
+#
+# Inputs:
+#  SIMD_STRING              A string describing the kind of SIMD support that didn't work.
+#  ALTERNATIVE_SUGGESTION   A string describing anything the user could try other than getting a new compiler.
+#  SUGGEST_BINUTILS_UPDATE  True when there's information that the compiler was OK, but something else was not.
+function(gmx_give_fatal_error_when_simd_support_not_found SIMD_STRING ALTERNATIVE_SUGGESTION SUGGEST_BINUTILS_UPDATE)
+    if(SUGGEST_BINUTILS_UPDATE)
+        set(_msg "Found a compiler flag for ${SIMD_STRING} support, but some other problem exists. Update your assembler and/or linker, e.g. in the binutils package of your distribution.")
+    else()
+        set(_msg "Cannot find ${SIMD_STRING} compiler flag. Use a newer compiler, or ${ALTERNATIVE_SUGGESTION}.")
+    endif()
+    message(FATAL_ERROR ${_msg})
+endfunction()
 
 macro(gmx_manage_simd)
 
@@ -103,7 +118,7 @@ elseif(GMX_SIMD STREQUAL "SSE2")
                                 "-msse2" "/arch:SSE2" "-hgnu")
 
     if(NOT CFLAGS_SSE2 OR NOT CXXFLAGS_SSE2)
-        message(FATAL_ERROR "Cannot find SSE2 compiler flag. Use a newer compiler, or disable SIMD (slower).")
+        gmx_give_fatal_error_when_simd_support_not_found("SSE2" "disable SIMD support (slow)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(GMX_SIMD_X86_SSE2 1)
@@ -124,8 +139,7 @@ elseif(GMX_SIMD STREQUAL "SSE4.1")
                                 "-msse4.1" "/arch:SSE4.1" "/arch:SSE2" "-hgnu")
 
     if(NOT CFLAGS_SSE4_1 OR NOT CXXFLAGS_SSE4_1)
-        message(FATAL_ERROR "Cannot find SSE4.1 compiler flag. "
-                            "Use a newer compiler, or choose SSE2 SIMD (slower).")
+        gmx_give_fatal_error_when_simd_support_not_found("SSE4.1" "choose SSE2 SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     if(CMAKE_C_COMPILER_ID MATCHES "Intel" AND CMAKE_C_COMPILER_VERSION VERSION_EQUAL "11.1")
@@ -184,7 +198,7 @@ int main(){__m128 x=_mm_set1_ps(0.5);x=_mm_macc_ps(x,x,x);return _mm_movemask_ps
 
     # We only need to check the last (FMA) test; that will always fail if the basic AVX128 test failed
     if(NOT CFLAGS_AVX_128_FMA OR NOT CXXFLAGS_AVX_128_FMA)
-        message(FATAL_ERROR "Cannot find compiler flags for 128 bit AVX with FMA support. Use a newer compiler, or choose SSE4.1 SIMD (slower).")
+        gmx_give_fatal_error_when_simd_support_not_found("128-bit AVX with FMA support" "choose SSE4.1 SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     ### STAGE 3: Optional: Find the XOP instruction flag (No point in yelling if this does not work)
@@ -244,7 +258,7 @@ elseif(GMX_SIMD STREQUAL "AVX_256")
                                 "-mavx" "/arch:AVX" "-hgnu")
 
     if(NOT CFLAGS_AVX OR NOT CXXFLAGS_AVX)
-        message(FATAL_ERROR "Cannot find AVX compiler flag. Use a newer compiler, or choose SSE4.1 SIMD (slower).")
+        gmx_give_fatal_error_when_simd_support_not_found("AVX" "choose SSE4.1 SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     gmx_test_avx_gcc_maskload_bug(GMX_SIMD_X86_AVX_GCC_MASKLOAD_BUG "${SIMD_C_FLAGS}")
@@ -268,7 +282,7 @@ elseif(GMX_SIMD STREQUAL "AVX2_256")
                                 "-march=core-avx2" "-mavx2" "/arch:AVX" "-hgnu") # no AVX2-specific flag for MSVC yet
 
     if(NOT CFLAGS_AVX2 OR NOT CXXFLAGS_AVX2)
-        message(FATAL_ERROR "Cannot find AVX2 compiler flag. Use a newer compiler, or choose AVX SIMD (slower).")
+        gmx_give_fatal_error_when_simd_support_not_found("AVX2" "choose AVX SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     # No need to test for Maskload bug - it was fixed before gcc added AVX2 support
@@ -298,7 +312,7 @@ elseif(GMX_SIMD STREQUAL "AVX_512F")
                                 "-xMIC-AVX512" "-mavx512f" "/arch:AVX" "-hgnu") # no AVX_512F flags known for MSVC yet
 
     if(NOT CFLAGS_AVX_512F OR NOT CXXFLAGS_AVX_512F)
-        message(FATAL_ERROR "Cannot find AVX 512F compiler flag. Use a newer compiler, or choose a lower level of SIMD")
+        gmx_give_fatal_error_when_simd_support_not_found("AVX 512F" "choose a lower level of SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(GMX_SIMD_X86_AVX_512F 1)
@@ -320,7 +334,7 @@ elseif(GMX_SIMD STREQUAL "AVX_512ER")
                                 "-xMIC-AVX512" "-mavx512er" "/arch:AVX" "-hgnu") # no AVX_512ER flags known for MSVC yet
 
     if(NOT CFLAGS_AVX_512ER OR NOT CXXFLAGS_AVX_512ER)
-        message(FATAL_ERROR "Cannot find AVX 512ER compiler flag. Use a newer compiler, or choose a lower level of SIMD")
+        gmx_give_fatal_error_when_simd_support_not_found("AVX 512ER" "choose a lower level of SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(GMX_SIMD_X86_AVX_512ER 1)
@@ -340,7 +354,7 @@ elseif(GMX_SIMD STREQUAL "ARM_NEON")
                                 "-mfpu=neon" "-D__STDC_CONSTANT_MACROS" "")
 
     if(NOT CFLAGS_ARM_NEON OR NOT CXXFLAGS_ARM_NEON)
-        message(FATAL_ERROR "Cannot find ARM 32-bit NEON compiler flag. Use a newer compiler, or disable NEON SIMD.")
+        gmx_give_fatal_error_when_simd_support_not_found("ARM 32-bit NEON" "disable SIMD support (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(GMX_SIMD_ARM_NEON 1)
@@ -362,7 +376,7 @@ elseif(GMX_SIMD STREQUAL "ARM_NEON_ASIMD")
                                 "-D__STDC_CONSTANT_MACROS" "")
 
     if(NOT CFLAGS_ARM_NEON_ASIMD OR NOT CXXFLAGS_ARM_NEON_ASIMD)
-        message(FATAL_ERROR "Cannot find ARM (AArch64) NEON Advanced SIMD compiler flag. Use a newer compiler, or disable SIMD.")
+        gmx_give_fatal_error_when_simd_support_not_found("ARM (AArch64) NEON Advanced SIMD" "disable SIMD support (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     if(CMAKE_C_COMPILER_ID MATCHES "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.9")
@@ -387,7 +401,7 @@ elseif(GMX_SIMD STREQUAL "IBM_QPX")
         set(SIMD_STATUS_MESSAGE "Enabling IBM QPX SIMD instructions")
 
     else()
-        message(FATAL_ERROR "Cannot compile the requested IBM QPX intrinsics. If you are compiling for BlueGene/Q with the XL compilers, use 'cmake .. -DCMAKE_TOOLCHAIN_FILE=Platform/BlueGeneQ-static-XL-C' to set up the tool chain.")
+        gmx_give_fatal_error_when_simd_support_not_found("IBM QPX" "or 'cmake .. -DCMAKE_TOOLCHAIN_FILE=Platform/BlueGeneQ-static-XL-CXX' to set up the tool chain" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
 elseif(GMX_SIMD STREQUAL "IBM_VMX")
@@ -404,7 +418,7 @@ elseif(GMX_SIMD STREQUAL "IBM_VMX")
                                 "-maltivec -mabi=altivec" "-qarch=auto -qaltivec")
 
     if(NOT CFLAGS_IBM_VMX OR NOT CXXFLAGS_IBM_VMX)
-        message(FATAL_ERROR "Cannot find IBM VMX SIMD compiler flag. Use a newer compiler, or disable VMX SIMD.")
+        gmx_give_fatal_error_when_simd_support_not_found("IBM VMX" "disable SIMD support (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(GMX_SIMD_IBM_VMX 1)
@@ -430,7 +444,7 @@ elseif(GMX_SIMD STREQUAL "IBM_VSX")
                                 "-mvsx" "-maltivec -mabi=altivec" "-qarch=auto -qaltivec")
 
     if(NOT CFLAGS_IBM_VSX OR NOT CXXFLAGS_IBM_VSX)
-        message(FATAL_ERROR "Cannot find IBM VSX SIMD compiler flag. Use a newer compiler, or disable VSX SIMD.")
+        gmx_give_fatal_error_when_simd_support_not_found("IBM VSX" "disable SIMD support (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(GMX_SIMD_IBM_VSX 1)
index 2f6b3afaa2f87e681ff0e4a54a083d16aab87fc7..c9e86f6a72666ff163ca2a425d5b5e409cf0d53b 100644 (file)
@@ -102,7 +102,10 @@ most recent version of your preferred compiler for your platform.
 There is a large amount of |Gromacs| code that depends on effective
 compiler optimization to get high performance. This makes |Gromacs|
 performance sensitive to the compiler used, and the binary will often
-only work on the hardware for which it is compiled.
+only work on the hardware for which it is compiled. You may also need
+the most recent version compiler toolchain components beside the
+compiler itself (e.g. assembler or linker); these are often shipped by
+the distribution's binutils package.
 
 * In particular, |Gromacs| includes a lot of explicit SIMD (single
   instruction, multiple data) optimization that suits