Improve CMake implementation for GMX_SIMD
authorMark Abraham <mark.j.abraham@gmail.com>
Sun, 2 Jul 2017 22:34:11 +0000 (00:34 +0200)
committerErik Lindahl <erik.lindahl@gmail.com>
Wed, 19 Jul 2017 06:28:55 +0000 (08:28 +0200)
It is robust to have cache variables that are user choices (and to
refrain from modifying them), or the result of system
introspection. We should not cache the result of subsequent
fast-running logic.

Introduced the new default for GMX_SIMD, which is AUTO. The value AUTO
triggers the same detection path that used to set the old "default",
producing the same SIMD choice, but leaves the value of GMX_SIMD as
what the user chose, ie "AUTO". That means e.g. ccmake will now show
the user their choice, not the result of the detection. The choice
is written to the status output each time it changes (even to and
from AUTO).

Explicit non-AUTO choices for GMX_SIMD work the same way they used to.

Simplified the implementation surrounding the run of the detection
code. We can just store the feature string if the run was successful,
and not otherwise, and that works also to prevent unecessary re-runs
of the detection.

This will now make it possible for us to implement other logic that
reacts to a SIMD choice differently according to whether it comes from
the user or detection.

The implementation of GMX_USE_RDTSCP now works better, because RDTSCP
is now on if the user chose an AVX-era SIMD level, off if an older
SIMD level was chosen, and suits the build host if the SIMD choice is
also automated to reflect the build host.

Moved a compiler-problem check to the SIMD-management code so that
it can use GMX_SIMD_CHOICE after it is defined.

The FFT-management code now uses GMX_SIMD_ACTIVE, which works because
it runs after the SIMD management, which uses a macro (so shares the
same variable scope as the calling code).

mdrun binary information still reports the actual choice, and not
whether it was based on AUTO.

Verifying that the rest of the code works correctly is complicated by
the way the SIMD module defines GMX_SIMD, and that is used e.g. by the
nbnxn, lincs and bonded code.

Minor fix to docs of gmx_check_if_changed.

Change-Id: I54e140394ea0c452450ebebad5782849e92a5ce2

CMakeLists.txt
cmake/gmxDetectSimd.cmake
cmake/gmxManageFFTLibraries.cmake
cmake/gmxManageSimd.cmake
cmake/gmxOptionUtilities.cmake
cmake/gmxTestCompilerProblems.cmake
src/config.h.cmakein
src/gromacs/gmxlib/nonbonded/CMakeLists.txt

index 3d36d3bde6556c26ffe12c0e810a2b8943725604..45bb40cadc931d682f9e20f345d68c5cb834777b 100644 (file)
@@ -236,14 +236,11 @@ else()
     endif()
 endif()
 
-include(gmxDetectSimd)
-gmx_detect_simd(GMX_SUGGESTED_SIMD)
-
 gmx_option_multichoice(
     GMX_SIMD
     "SIMD instruction set for CPU kernels and compiler optimization"
-    "${GMX_SUGGESTED_SIMD}"
-    None SSE2 SSE4.1 AVX_128_FMA AVX_256 AVX2_256 AVX2_128 AVX_512 AVX_512_KNL MIC ARM_NEON ARM_NEON_ASIMD IBM_QPX IBM_VMX IBM_VSX Sparc64_HPC_ACE Reference)
+    "AUTO"
+    AUTO None SSE2 SSE4.1 AVX_128_FMA AVX_256 AVX2_256 AVX2_128 AVX_512 AVX_512_KNL MIC ARM_NEON ARM_NEON_ASIMD IBM_QPX IBM_VMX IBM_VSX Sparc64_HPC_ACE Reference)
 
 if(GMX_TARGET_MIC)
     set(GMX_FFT_LIBRARY_DEFAULT "mkl")
@@ -624,7 +621,7 @@ gmx_set_build_information()
 # TODO: After merge with 5.0 one could implement a cache variable dependency
 # such that GMX_USE_RDTSCP can change if GMX_SIMD is changed to AVX
 # after the first cmake pass.
-if (CPU_DETECTION_FEATURES MATCHES "rdtscp" OR GMX_SIMD MATCHES "AVX")
+if ((GMX_SIMD STREQUAL "AUTO" AND CPU_DETECTION_FEATURES MATCHES "rdtscp") OR (GMX_SIMD MATCHES "AVX"))
     set(GMX_USE_RDTSCP_DEFAULT_VALUE ON)
 else()
     set(GMX_USE_RDTSCP_DEFAULT_VALUE OFF)
index 9fa54c1420eea5c26d4cfdd7cdabdacdf960712e..e83c3abd790d0e6c65d6a22b2a0a76eb321af918 100644 (file)
@@ -122,7 +122,7 @@ function(gmx_suggest_simd _suggested_simd)
 endfunction()
 
 function(gmx_detect_simd _suggested_simd)
-    if(NOT DEFINED GMX_SIMD)
+    if(GMX_SIMD STREQUAL "AUTO")
         if(GMX_TARGET_BGQ)
             # BG/Q requires cross-compilation, so needs this
             # logic. While the qpx feature flag in cpuinfo works, it
index 800b2f633ca71fe5dec3230db5fee93413598e8f..f0ef27f6d6422b8d271ba5cdb02ba6babdb8325b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2012,2013,2014,2015,2016, by the GROMACS development team, led by
+# Copyright (c) 2012,2013,2014,2015,2016,2017, 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.
@@ -89,10 +89,10 @@ if(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
         set(PKG_FFT "${${FFTW}_PKG}")
         include_directories(SYSTEM ${${FFTW}_INCLUDE_DIRS})
 
-        if ((${GMX_SIMD} MATCHES "SSE" OR ${GMX_SIMD} MATCHES "AVX") AND NOT ${FFTW}_HAVE_SIMD)
+        if ((${GMX_SIMD_ACTIVE} MATCHES "SSE" OR ${GMX_SIMD_ACTIVE} 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))
+            if(${GMX_SIMD_ACTIVE} 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.
                 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 --enable-sse2 and --enable-avx (and --enable-avx2 or --enable-avx512 if supported).")
index b5d84a1a6cce8f355698d8f772dbf3a47b60851b..64661de6f9e07e8eb1e49fb36e109a49e28891cb 100644 (file)
@@ -126,33 +126,41 @@ endif()
 #
 # Section to set (and test) compiler flags for SIMD.
 #
-# The flags will be set based on the GMX_SIMD choice provided by the user.
-# Automatic detection of the architecture on the build host is done prior to
-# calling this macro.
+# If the user chose the (default) automatic behaviour, then detection
+# is run to suggest a SIMD choice suitable for the build
+# host. Otherwise, the users's choice is always honoured. The compiler
+# flags will be set based on that choice.
 #
 
-if(GMX_SIMD STREQUAL "NONE")
+set(GMX_SIMD_ACTIVE ${GMX_SIMD})
+if(GMX_SIMD STREQUAL "AUTO")
+    include(gmxDetectSimd)
+    gmx_detect_simd(GMX_SUGGESTED_SIMD)
+    set(GMX_SIMD_ACTIVE ${GMX_SUGGESTED_SIMD})
+endif()
+
+if(GMX_SIMD_ACTIVE STREQUAL "NONE")
     # nothing to do configuration-wise
     set(SIMD_STATUS_MESSAGE "SIMD instructions disabled")
-elseif(GMX_SIMD STREQUAL "SSE2")
+elseif(GMX_SIMD_ACTIVE STREQUAL "SSE2")
 
     gmx_find_flags(
         "#include<xmmintrin.h>
          int main(){__m128 x=_mm_set1_ps(0.5);x=_mm_rsqrt_ps(x);return _mm_movemask_ps(x);}"
         TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS
-        SIMD_${GMX_SIMD}_C_FLAGS SIMD_${GMX_SIMD}_CXX_FLAGS
+        SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS
         "-msse2" "/arch:SSE2" "-hgnu")
 
-    if(NOT SIMD_${GMX_SIMD}_C_FLAGS OR NOT SIMD_${GMX_SIMD}_CXX_FLAGS)
+    if(NOT SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS OR NOT SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS)
         gmx_give_fatal_error_when_simd_support_not_found("SSE2" "disable SIMD support (slow)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(SIMD_C_FLAGS "${TOOLCHAIN_C_FLAGS}")
     set(SIMD_CXX_FLAGS "${TOOLCHAIN_CXX_FLAGS}")
-    set(GMX_SIMD_X86_${GMX_SIMD} 1)
+    set(GMX_SIMD_X86_${GMX_SIMD_ACTIVE} 1)
     set(SIMD_STATUS_MESSAGE "Enabling SSE2 SIMD instructions")
 
-elseif(GMX_SIMD STREQUAL "SSE4.1")
+elseif(GMX_SIMD_ACTIVE STREQUAL "SSE4.1")
 
     # Note: MSVC enables SSE4.1 with the SSE2 flag, so we include that in testing.
     gmx_find_flags(
@@ -171,7 +179,7 @@ elseif(GMX_SIMD STREQUAL "SSE4.1")
     set(GMX_SIMD_X86_SSE4_1 1)
     set(SIMD_STATUS_MESSAGE "Enabling SSE4.1 SIMD instructions")
 
-elseif(GMX_SIMD STREQUAL "AVX_128_FMA")
+elseif(GMX_SIMD_ACTIVE STREQUAL "AVX_128_FMA")
 
     prepare_x86_toolchain(TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS)
 
@@ -229,11 +237,11 @@ elseif(GMX_SIMD STREQUAL "AVX_128_FMA")
         ${INCLUDE_INTRIN_H}
         int main(){__m128 x=_mm_set1_ps(0.5);x=_mm_macc_ps(x,x,x);return _mm_movemask_ps(x);}"
         TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS
-        SIMD_${GMX_SIMD}_C_FLAGS SIMD_${GMX_SIMD}_CXX_FLAGS
+        SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS
         "-mfma4" "-hgnu")
 
     # We only need to check the last (FMA) test; that will always fail if the generic AVX test failed
-    if(NOT SIMD_${GMX_SIMD}_C_FLAGS OR NOT SIMD_${GMX_SIMD}_CXX_FLAGS)
+    if(NOT SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS OR NOT SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS)
         gmx_give_fatal_error_when_simd_support_not_found("128-bit AVX with FMA support" "choose SSE4.1 SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
@@ -249,10 +257,10 @@ elseif(GMX_SIMD STREQUAL "AVX_128_FMA")
 
     set(SIMD_C_FLAGS "${TOOLCHAIN_C_FLAGS}")
     set(SIMD_CXX_FLAGS "${TOOLCHAIN_CXX_FLAGS}")
-    set(GMX_SIMD_X86_${GMX_SIMD} 1)
+    set(GMX_SIMD_X86_${GMX_SIMD_ACTIVE} 1)
     set(SIMD_STATUS_MESSAGE "Enabling 128-bit AVX SIMD GROMACS SIMD (with fused-multiply add)")
 
-elseif(GMX_SIMD STREQUAL "AVX_256")
+elseif(GMX_SIMD_ACTIVE STREQUAL "AVX_256")
 
     prepare_x86_toolchain(TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS)
 
@@ -260,19 +268,19 @@ elseif(GMX_SIMD STREQUAL "AVX_256")
         "#include<immintrin.h>
          int main(){__m256 x=_mm256_set1_ps(0.5);x=_mm256_add_ps(x,x);return _mm256_movemask_ps(x);}"
         TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS
-        SIMD_${GMX_SIMD}_C_FLAGS SIMD_${GMX_SIMD}_CXX_FLAGS
+        SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS
         "-mavx" "/arch:AVX" "-hgnu")
 
-    if(NOT SIMD_${GMX_SIMD}_C_FLAGS OR NOT SIMD_${GMX_SIMD}_CXX_FLAGS)
+    if(NOT SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS OR NOT SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS)
         gmx_give_fatal_error_when_simd_support_not_found("AVX" "choose SSE4.1 SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(SIMD_C_FLAGS "${TOOLCHAIN_C_FLAGS}")
     set(SIMD_CXX_FLAGS "${TOOLCHAIN_CXX_FLAGS}")
-    set(GMX_SIMD_X86_${GMX_SIMD} 1)
+    set(GMX_SIMD_X86_${GMX_SIMD_ACTIVE} 1)
     set(SIMD_STATUS_MESSAGE "Enabling 256-bit AVX SIMD instructions")
 
-elseif(GMX_SIMD MATCHES "AVX2_")
+elseif(GMX_SIMD_ACTIVE MATCHES "AVX2_")
 
     prepare_x86_toolchain(TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS)
 
@@ -280,30 +288,30 @@ elseif(GMX_SIMD MATCHES "AVX2_")
         "#include<immintrin.h>
          int main(){__m256i x=_mm256_set1_epi32(5);x=_mm256_add_epi32(x,x);return _mm256_movemask_epi8(x);}"
         TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS
-        SIMD_${GMX_SIMD}_C_FLAGS SIMD_${GMX_SIMD}_CXX_FLAGS
+        SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS
         "-march=core-avx2" "-mavx2" "/arch:AVX" "-hgnu") # no AVX2-specific flag for MSVC yet
 
-    if(NOT SIMD_${GMX_SIMD}_C_FLAGS OR NOT SIMD_${GMX_SIMD}_CXX_FLAGS)
+    if(NOT SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS OR NOT SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS)
         gmx_give_fatal_error_when_simd_support_not_found("AVX2" "choose AVX SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(SIMD_C_FLAGS "${TOOLCHAIN_C_FLAGS}")
     set(SIMD_CXX_FLAGS "${TOOLCHAIN_CXX_FLAGS}")
-    set(GMX_SIMD_X86_${GMX_SIMD} 1)
+    set(GMX_SIMD_X86_${GMX_SIMD_ACTIVE} 1)
 
-    if(GMX_SIMD STREQUAL "AVX2_128")
+    if(GMX_SIMD_ACTIVE STREQUAL "AVX2_128")
         set(SIMD_STATUS_MESSAGE "Enabling 128-bit AVX2 SIMD instructions")
     else()
         set(SIMD_STATUS_MESSAGE "Enabling 256-bit AVX2 SIMD instructions")
     endif()
 
-elseif(GMX_SIMD STREQUAL "MIC")
+elseif(GMX_SIMD_ACTIVE STREQUAL "MIC")
 
     # No flags needed. Not testing.
     set(GMX_SIMD_X86_MIC 1)
     set(SIMD_STATUS_MESSAGE "Enabling MIC (Xeon Phi) SIMD instructions")
 
-elseif(GMX_SIMD STREQUAL "AVX_512")
+elseif(GMX_SIMD_ACTIVE STREQUAL "AVX_512")
 
     prepare_x86_toolchain(TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS)
 
@@ -311,19 +319,19 @@ elseif(GMX_SIMD STREQUAL "AVX_512")
         "#include<immintrin.h>
          int main(){__m512 y,x=_mm512_set1_ps(0.5);y=_mm512_fmadd_ps(x,x,x);return (int)_mm512_cmp_ps_mask(x,y,_CMP_LT_OS);}"
         TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS
-        SIMD_${GMX_SIMD}_C_FLAGS SIMD_${GMX_SIMD}_CXX_FLAGS
+        SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS
         "-xCORE-AVX512" "-mavx512f -mfma" "-mavx512f" "/arch:AVX" "-hgnu") # no AVX_512F flags known for MSVC yet
 
-    if(NOT SIMD_${GMX_SIMD}_C_FLAGS OR NOT SIMD_${GMX_SIMD}_CXX_FLAGS)
+    if(NOT SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS OR NOT SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS)
         gmx_give_fatal_error_when_simd_support_not_found("AVX 512F" "choose a lower level of SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(SIMD_C_FLAGS "${TOOLCHAIN_C_FLAGS}")
     set(SIMD_CXX_FLAGS "${TOOLCHAIN_CXX_FLAGS}")
-    set(GMX_SIMD_X86_${GMX_SIMD} 1)
+    set(GMX_SIMD_X86_${GMX_SIMD_ACTIVE} 1)
     set(SIMD_STATUS_MESSAGE "Enabling 512-bit AVX-512 SIMD instructions")
 
-elseif(GMX_SIMD STREQUAL "AVX_512_KNL")
+elseif(GMX_SIMD_ACTIVE STREQUAL "AVX_512_KNL")
 
     prepare_x86_toolchain(TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS)
 
@@ -331,87 +339,87 @@ elseif(GMX_SIMD STREQUAL "AVX_512_KNL")
         "#include<immintrin.h>
         int main(){__m512 y,x=_mm512_set1_ps(0.5);y=_mm512_rsqrt28_ps(x);return (int)_mm512_cmp_ps_mask(x,y,_CMP_LT_OS);}"
         TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS
-        SIMD_${GMX_SIMD}_C_FLAGS SIMD_${GMX_SIMD}_CXX_FLAGS
+        SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS
         "-xMIC-AVX512" "-mavx512er -mfma" "-mavx512er" "/arch:AVX" "-hgnu") # no AVX_512ER flags known for MSVC yet
 
-    if(NOT SIMD_${GMX_SIMD}_C_FLAGS OR NOT SIMD_${GMX_SIMD}_CXX_FLAGS)
+    if(NOT SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS OR NOT SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS)
         gmx_give_fatal_error_when_simd_support_not_found("AVX 512ER" "choose a lower level of SIMD (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(SIMD_C_FLAGS "${TOOLCHAIN_C_FLAGS}")
     set(SIMD_CXX_FLAGS "${TOOLCHAIN_CXX_FLAGS}")
-    set(GMX_SIMD_X86_${GMX_SIMD} 1)
+    set(GMX_SIMD_X86_${GMX_SIMD_ACTIVE} 1)
     set(SIMD_STATUS_MESSAGE "Enabling 512-bit AVX-512-KNL SIMD instructions")
 
-elseif(GMX_SIMD STREQUAL "ARM_NEON")
+elseif(GMX_SIMD_ACTIVE STREQUAL "ARM_NEON")
 
     gmx_find_flags(
         "#include<arm_neon.h>
          int main(){float32x4_t x=vdupq_n_f32(0.5);x=vmlaq_f32(x,x,x);return vgetq_lane_f32(x,0)>0;}"
         TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS
-        SIMD_${GMX_SIMD}_C_FLAGS SIMD_${GMX_SIMD}_CXX_FLAGS
+        SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS
         "-mfpu=neon-vfpv4" "-mfpu=neon" "")
 
-    if(NOT SIMD_${GMX_SIMD}_C_FLAGS OR NOT SIMD_${GMX_SIMD}_CXX_FLAGS)
+    if(NOT SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS OR NOT SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS)
         gmx_give_fatal_error_when_simd_support_not_found("ARM NEON" "disable SIMD support (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(SIMD_C_FLAGS "${TOOLCHAIN_C_FLAGS}")
     set(SIMD_CXX_FLAGS "${TOOLCHAIN_CXX_FLAGS}")
-    set(GMX_SIMD_${GMX_SIMD} 1)
+    set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
     set(SIMD_STATUS_MESSAGE "Enabling 32-bit ARM NEON SIMD instructions")
 
-elseif(GMX_SIMD STREQUAL "ARM_NEON_ASIMD")
+elseif(GMX_SIMD_ACTIVE STREQUAL "ARM_NEON_ASIMD")
 
     gmx_find_flags(
         "#include<arm_neon.h>
          int main(){float64x2_t x=vdupq_n_f64(0.5);x=vfmaq_f64(x,x,x);x=vrndnq_f64(x);return vgetq_lane_f64(x,0)>0;}"
         TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS
-        SIMD_${GMX_SIMD}_C_FLAGS SIMD_${GMX_SIMD}_CXX_FLAGS
+        SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS
         "")
 
-    if(NOT SIMD_${GMX_SIMD}_C_FLAGS OR NOT SIMD_${GMX_SIMD}_CXX_FLAGS)
+    if(NOT SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS OR NOT SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS)
         gmx_give_fatal_error_when_simd_support_not_found("ARM (AArch64) NEON Advanced SIMD" "particularly gcc version 4.9 or later, or disable SIMD support (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(SIMD_C_FLAGS "${TOOLCHAIN_C_FLAGS}")
     set(SIMD_CXX_FLAGS "${TOOLCHAIN_CXX_FLAGS}")
-    set(GMX_SIMD_${GMX_SIMD} 1)
+    set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
     set(SIMD_STATUS_MESSAGE "Enabling ARM (AArch64) NEON Advanced SIMD instructions")
 
-elseif(GMX_SIMD STREQUAL "IBM_QPX")
+elseif(GMX_SIMD_ACTIVE STREQUAL "IBM_QPX")
 
     try_compile(TEST_QPX ${CMAKE_BINARY_DIR}
         "${CMAKE_SOURCE_DIR}/cmake/TestQPX.c")
 
     if (TEST_QPX)
         message(WARNING "IBM QPX SIMD instructions selected. This will work, but SIMD kernels are only available for the Verlet cut-off scheme. The plain C kernels that are used for the group cut-off scheme kernels will be slow, so please consider using the Verlet cut-off scheme.")
-        set(GMX_SIMD_${GMX_SIMD} 1)
+        set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
         set(SIMD_STATUS_MESSAGE "Enabling IBM QPX SIMD instructions")
 
     else()
         gmx_give_fatal_error_when_simd_support_not_found("IBM QPX" "or 'cmake .. -DCMAKE_TOOLCHAIN_FILE=Platform/BlueGeneQ-static-bgclang-CXX' to set up the tool chain" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
-elseif(GMX_SIMD STREQUAL "IBM_VMX")
+elseif(GMX_SIMD_ACTIVE STREQUAL "IBM_VMX")
 
     gmx_find_flags(
         "#include<altivec.h>
          int main(){vector float x,y=vec_ctf(vec_splat_s32(1),0);x=vec_madd(y,y,y);return vec_all_ge(y,x);}"
         TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS
-        SIMD_${GMX_SIMD}_C_FLAGS SIMD_${GMX_SIMD}_CXX_FLAGS
+        SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS
         "-maltivec -mabi=altivec" "-qarch=auto -qaltivec")
 
-    if(NOT SIMD_${GMX_SIMD}_C_FLAGS OR NOT SIMD_${GMX_SIMD}_CXX_FLAGS)
+    if(NOT SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS OR NOT SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS)
         gmx_give_fatal_error_when_simd_support_not_found("IBM VMX" "disable SIMD support (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(SIMD_C_FLAGS "${TOOLCHAIN_C_FLAGS}")
     set(SIMD_CXX_FLAGS "${TOOLCHAIN_CXX_FLAGS}")
-    set(GMX_SIMD_${GMX_SIMD} 1)
+    set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
     set(SIMD_STATUS_MESSAGE "Enabling IBM VMX SIMD instructions")
 
-elseif(GMX_SIMD STREQUAL "IBM_VSX")
+elseif(GMX_SIMD_ACTIVE STREQUAL "IBM_VSX")
 
     prepare_power_vsx_toolchain(TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS)
 
@@ -419,7 +427,7 @@ elseif(GMX_SIMD STREQUAL "IBM_VSX")
         "#include<altivec.h>
          int main(){vector double x,y=vec_splats(1.0);x=vec_madd(y,y,y);return vec_all_ge(y,x);}"
         TOOLCHAIN_C_FLAGS TOOLCHAIN_CXX_FLAGS
-        SIMD_${GMX_SIMD}_C_FLAGS SIMD_${GMX_SIMD}_CXX_FLAGS
+        SIMD_${GMX_SIMD_ACTIVE}_C_FLAGS SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS
         "-mvsx" "-maltivec -mabi=altivec" "-qarch=auto -qaltivec")
 
     # Usually we check also for the C compiler here, but a C compiler
@@ -427,23 +435,23 @@ elseif(GMX_SIMD STREQUAL "IBM_VSX")
     # at least version 3.7 cannot pass this check with the C compiler
     # in the latest xlc 13.1.5, but the C++ compiler has different
     # behaviour and is OK. See Redmine #2102.
-    if(NOT SIMD_${GMX_SIMD}_CXX_FLAGS)
+    if(NOT SIMD_${GMX_SIMD_ACTIVE}_CXX_FLAGS)
         gmx_give_fatal_error_when_simd_support_not_found("IBM VSX" "disable SIMD support (slower)" "${SUGGEST_BINUTILS_UPDATE}")
     endif()
 
     set(SIMD_C_FLAGS "${TOOLCHAIN_C_FLAGS}")
     set(SIMD_CXX_FLAGS "${TOOLCHAIN_CXX_FLAGS}")
-    set(GMX_SIMD_${GMX_SIMD} 1)
+    set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
     set(SIMD_STATUS_MESSAGE "Enabling IBM VSX SIMD instructions")
 
-elseif(GMX_SIMD STREQUAL "SPARC64_HPC_ACE")
+elseif(GMX_SIMD_ACTIVE STREQUAL "SPARC64_HPC_ACE")
 
     # Note that GMX_RELAXED_DOUBLE_PRECISION is enabled by default in the top-level CMakeLists.txt
 
-    set(GMX_SIMD_${GMX_SIMD} 1)
+    set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
     set(SIMD_STATUS_MESSAGE "Enabling Sparc64 HPC-ACE SIMD instructions")
 
-elseif(GMX_SIMD STREQUAL "REFERENCE")
+elseif(GMX_SIMD_ACTIVE STREQUAL "REFERENCE")
 
     # NB: This file handles settings for the SIMD module, so in the interest 
     # of proper modularization, please do NOT put any verlet kernel settings in this file.
@@ -455,15 +463,15 @@ elseif(GMX_SIMD STREQUAL "REFERENCE")
        add_definitions(-DGMX_SIMD_REF_DOUBLE_WIDTH=${GMX_SIMD_REF_DOUBLE_WIDTH})
     endif()
 
-    set(GMX_SIMD_${GMX_SIMD} 1)
+    set(GMX_SIMD_${GMX_SIMD_ACTIVE} 1)
     set(SIMD_STATUS_MESSAGE "Enabling reference (emulated) SIMD instructions.")
 
 else()
-    gmx_invalid_option_value(GMX_SIMD)
+    gmx_invalid_option_value(GMX_SIMD_ACTIVE)
 endif()
 
 
-gmx_check_if_changed(SIMD_CHANGED GMX_SIMD)
+gmx_check_if_changed(SIMD_CHANGED GMX_SIMD_ACTIVE)
 if (SIMD_CHANGED AND DEFINED SIMD_STATUS_MESSAGE)
     message(STATUS "${SIMD_STATUS_MESSAGE}")
 endif()
@@ -491,7 +499,7 @@ endif()
 if(NOT DEFINED GMX_SIMD_CALLING_CONVENTION)
     if(GMX_TARGET_BGQ)
         set(CALLCONV_LIST " ")
-    elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND GMX_SIMD STREQUAL "REFERENCE")
+    elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND GMX_SIMD_ACTIVE STREQUAL "REFERENCE")
         set(CALLCONV_LIST __regcall " ")
    elseif(CMAKE_CXX_COMPILER_ID MATCHES "XL")
         set(CALLCONV_LIST " ")
@@ -508,5 +516,14 @@ if(NOT DEFINED GMX_SIMD_CALLING_CONVENTION)
     endforeach()
 endif()
 
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+    # GCC bug 49001, 54412 on Windows (just warn, since it might be fixed in later versions)
+    if((CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9.0" OR CMAKE_SIZEOF_VOID_P EQUAL 8)
+            AND (WIN32 OR CYGWIN)
+            AND (GMX_SIMD_ACTIVE MATCHES "AVX") AND NOT (GMX_SIMD_ACTIVE STREQUAL "AVX_128_FMA"))
+        message(WARNING "GCC on Windows (GCC older than 4.9 in 32-bit mode, or any version in 64-bit mode) with 256-bit AVX will probably crash. You might want to choose a different GMX_SIMD or a different compiler.")
+    endif()
+endif()
+
 endmacro()
 
index b698cd68793da249f58ff60e8b6cf0764f37724d..01b55c93ce2b74c72a240ade7ae692907d6e1e21 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+# Copyright (c) 2013,2014,2015,2017, 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.
@@ -210,13 +210,13 @@ function (GMX_SET_BOOLEAN NAME CONDITIONS)
     set(${NAME} ${${NAME}} PARENT_SCOPE)
 endfunction()
 
-# Checks if one or more cache variables have changed
+# Checks if one or more variables have changed since last call to this function
 #
 # Usage:
 #   gmx_check_if_changed(RESULT VAR1 VAR2 ... VARN)
 #
-# Sets RESULT to true if any of the given cache variables VAR1 ... VARN has
-# changes since the last call to this function for that variable.
+# Sets RESULT to true if any of the given variables VAR1 ... VARN has
+# changed since the last call to this function for that variable.
 # Changes are tracked also across CMake runs.
 function(GMX_CHECK_IF_CHANGED RESULT)
     set(_result FALSE)
index 26eeb298df4c1c7497abd12f3dfb906491f6e494..2d55e192f02dd3ff4fdc3bc1dccbd1236df0633c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2012,2013,2014,2015,2016, by the GROMACS development team, led by
+# Copyright (c) 2012,2013,2014,2015,2016,2017, 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.
@@ -45,15 +45,7 @@ macro(gmx_test_compiler_problems)
     endif()
 
     # Note that we've already tested that the compiler works with C++11
-    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
-
-        # GCC bug 49001, 54412 on Windows (just warn, since it might be fixed in later versions)
-        if((CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9.0" OR CMAKE_SIZEOF_VOID_P EQUAL 8)
-           AND (WIN32 OR CYGWIN)
-           AND (GMX_SIMD MATCHES "AVX") AND NOT (GMX_SIMD STREQUAL AVX_128_FMA))
-            message(WARNING "GCC on Windows (GCC older than 4.9 in 32-bit mode, or any version in 64-bit mode) with 256-bit AVX will probably crashes. You might want to choose a different GMX_SIMD or a different compiler.")
-        endif()
-    elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
         if(WIN32 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.5.0")
             message(WARNING "Using Clang on Windows requires Clang 3.5.0")
         endif()
index 0d2c7fb10c381a378db7e11f715fc3b6dd1d5605..5036e0f9494d167b7f76aa7a24d8c9e5521d5302 100644 (file)
 #cmakedefine01 GMX_SIMD_REFERENCE
 
 /* String for SIMD instruction choice (for writing to log files and stdout) */
-#define GMX_SIMD_STRING "@GMX_SIMD@"
+#define GMX_SIMD_STRING "@GMX_SIMD_ACTIVE@"
 
 /* Calling convention string (if any) for routines with SIMD variable args */
 #define gmx_simdcall @GMX_SIMD_CALLING_CONVENTION@
index a1259c76eff00bc99b3338134010e2115bc85006..69b077b6ab4e7fc1290126f5a99577bde78321ae 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,2017, 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.
 # Sources that should always be built
 file(GLOB NONBONDED_SOURCES *.cpp nb_kernel_c/*.c)
 
-if("${GMX_SIMD}" STREQUAL "SSE2" AND NOT GMX_DOUBLE)
+if("${GMX_SIMD_ACTIVE}" STREQUAL "SSE2" AND NOT GMX_DOUBLE)
     file(GLOB NONBONDED_SSE2_SINGLE_SOURCES nb_kernel_sse2_single/*.c)
 endif()
 
-if("${GMX_SIMD}" STREQUAL "SSE4.1" AND NOT GMX_DOUBLE)
+if("${GMX_SIMD_ACTIVE}" STREQUAL "SSE4.1" AND NOT GMX_DOUBLE)
     file(GLOB NONBONDED_SSE4_1_SINGLE_SOURCES nb_kernel_sse4_1_single/*.c)
 endif()
 
-if("${GMX_SIMD}" STREQUAL "AVX_128_FMA" AND NOT GMX_DOUBLE)
+if("${GMX_SIMD_ACTIVE}" STREQUAL "AVX_128_FMA" AND NOT GMX_DOUBLE)
     file(GLOB NONBONDED_AVX_128_FMA_SINGLE_SOURCES nb_kernel_avx_128_fma_single/*.c)
 endif()
 
-if((("${GMX_SIMD}" STREQUAL "AVX_256") OR ("${GMX_SIMD}" STREQUAL "AVX2_256")) AND NOT GMX_DOUBLE)
+if((("${GMX_SIMD_ACTIVE}" STREQUAL "AVX_256") OR ("${GMX_SIMD_ACTIVE}" STREQUAL "AVX2_256")) AND NOT GMX_DOUBLE)
     file(GLOB NONBONDED_AVX_256_SINGLE_SOURCES nb_kernel_avx_256_single/*.c)
 endif()
 
-if("${GMX_SIMD}" STREQUAL "SSE2" AND GMX_DOUBLE)
+if("${GMX_SIMD_ACTIVE}" STREQUAL "SSE2" AND GMX_DOUBLE)
     file(GLOB NONBONDED_SSE2_DOUBLE_SOURCES nb_kernel_sse2_double/*.c)
 endif()
 
-if("${GMX_SIMD}" STREQUAL "SSE4.1" AND GMX_DOUBLE)
+if("${GMX_SIMD_ACTIVE}" STREQUAL "SSE4.1" AND GMX_DOUBLE)
     file(GLOB NONBONDED_SSE4_1_DOUBLE_SOURCES nb_kernel_sse4_1_double/*.c)
 endif()
 
-if("${GMX_SIMD}" STREQUAL "AVX_128_FMA" AND GMX_DOUBLE)
+if("${GMX_SIMD_ACTIVE}" STREQUAL "AVX_128_FMA" AND GMX_DOUBLE)
     file(GLOB NONBONDED_AVX_128_FMA_DOUBLE_SOURCES nb_kernel_avx_128_fma_double/*.c)
 endif()
 
-if((("${GMX_SIMD}" STREQUAL "AVX_256") OR ("${GMX_SIMD}" STREQUAL "AVX2_256")) AND GMX_DOUBLE)
+if((("${GMX_SIMD_ACTIVE}" STREQUAL "AVX_256") OR ("${GMX_SIMD_ACTIVE}" STREQUAL "AVX2_256")) AND GMX_DOUBLE)
     file(GLOB NONBONDED_AVX_256_DOUBLE_SOURCES nb_kernel_avx_256_double/*.c)
 endif()
 
-if("${GMX_SIMD}" STREQUAL "SPARC64_HPC_ACE" AND GMX_DOUBLE)
+if("${GMX_SIMD_ACTIVE}" STREQUAL "SPARC64_HPC_ACE" AND GMX_DOUBLE)
     file(GLOB NONBONDED_SPARC64_HPC_ACE_DOUBLE_SOURCES nb_kernel_sparc64_hpc_ace_double/*.c)
 endif()