CMake helper for tracking cache variable changes.
authorTeemu Murtola <teemu.murtola@gmail.com>
Fri, 24 May 2013 15:37:40 +0000 (18:37 +0300)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Thu, 3 Oct 2013 20:36:54 +0000 (22:36 +0200)
Used the new macro for controlling when to output various status
messages, making the output more useful to see that user-made changes
really had the desired effect.

Change-Id: I21b791ab8e4f3c8d22981b2315db96e8983c0b26

CMakeLists.txt
cmake/gmxManageLinearAlgebraLibraries.cmake
cmake/gmxOptionUtilities.cmake

index 477c742764f7277e4c0462692ed78840e8e1277d..61f0a489255dfffef21aa59278865dd91b71b10f 100644 (file)
@@ -679,6 +679,8 @@ include(gmxTestAVXMaskload)
 # requiring such backward compatibility is all located here.
 if(${GMX_CPU_ACCELERATION} STREQUAL "NONE")
     # nothing to do
+    set(ACCELERATION_STATUS_MESSAGE "CPU acceleration disabled")
+
 elseif(${GMX_CPU_ACCELERATION} STREQUAL "SSE2")
 
     GMX_TEST_CFLAG(GNU_SSE2_CFLAG "-msse2" ACCELERATION_C_FLAGS)
@@ -703,9 +705,8 @@ elseif(${GMX_CPU_ACCELERATION} STREQUAL "SSE2")
     set(GMX_CPU_ACCELERATION_X86_SSE2 1)
     # The user should not be able to set this orthogonally to the acceleration
     set(GMX_X86_SSE2 1)
-    if (NOT ACCELERATION_QUIETLY)
-      message(STATUS "Enabling SSE2 Gromacs acceleration, and it will help compiler optimization.")
-    endif()
+    set(ACCELERATION_STATUS_MESSAGE
+        "Enabling SSE2 Gromacs acceleration, and it will help compiler optimization.")
 
 elseif(${GMX_CPU_ACCELERATION} STREQUAL "SSE4.1")
 
@@ -744,17 +745,17 @@ elseif(${GMX_CPU_ACCELERATION} STREQUAL "SSE4.1")
         message(FATAL_ERROR "Cannot find smmintrin.h, which is required for SSE4.1 intrinsics support.")
     endif(NOT HAVE_SMMINTRIN_H)
 
+    if(CMAKE_C_COMPILER_ID MATCHES "Intel" AND C_COMPILER_VERSION VERSION_EQUAL "11.1")
+        message(FATAL_ERROR "You are using Intel compiler version 11.1, and that compiler is known to produce incorrect results with SSE4.1 acceleration. You need to use another compiler (e.g. icc 12 or newer) or different acceleration (probably slower simulations).")
+    endif()
+
     set(GMX_CPU_ACCELERATION_X86_SSE4_1 1)
     # The user should not be able to set this orthogonally to the acceleration
     set(GMX_X86_SSE4_1 1)
     set(GMX_X86_SSE2   1)
-    if (NOT ACCELERATION_QUIETLY)
-      message(STATUS "Enabling SSE4.1 Gromacs acceleration, and it will help compiler optimization.")
-    endif()
+    set(ACCELERATION_STATUS_MESSAGE
+        "Enabling SSE4.1 Gromacs acceleration, and it will help compiler optimization.")
 
-    if(CMAKE_C_COMPILER_ID MATCHES "Intel" AND C_COMPILER_VERSION VERSION_EQUAL "11.1")
-        message(FATAL_ERROR "You are using Intel compiler version 11.1, and that compiler is known to produce incorrect results with SSE4.1 acceleration. You need to use another compiler (e.g. icc 12 or newer) or different acceleration (probably slower simulations).")
-    endif()
 elseif(${GMX_CPU_ACCELERATION} STREQUAL "AVX_128_FMA" OR ${GMX_CPU_ACCELERATION} STREQUAL "AVX_256")
 
     # Set the AVX compiler flag for both these choices!
@@ -817,12 +818,6 @@ elseif(${GMX_CPU_ACCELERATION} STREQUAL "AVX_128_FMA" OR ${GMX_CPU_ACCELERATION}
 
     # But just enable one of the choices internally...
     if(${GMX_CPU_ACCELERATION} STREQUAL "AVX_128_FMA")
-        set(GMX_CPU_ACCELERATION_X86_AVX_128_FMA 1)
-        set(GMX_X86_AVX_128_FMA 1)
-        if (NOT ACCELERATION_QUIETLY)
-          message(STATUS "Enabling 128-bit AVX Gromacs acceleration (with fused-multiply add), and it will help compiler optimization.")
-        endif()
-
         # We don't have the full compiler version string yet (BUILD_C_COMPILER),
         # so we can't distinguish vanilla and Apple clang, but catering for AMD
         # hackintoshes is not worth the effort.
@@ -842,13 +837,17 @@ elseif(${GMX_CPU_ACCELERATION} STREQUAL "AVX_128_FMA" OR ${GMX_CPU_ACCELERATION}
             set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -no-integrated-as")
         endif()
 
+        set(GMX_CPU_ACCELERATION_X86_AVX_128_FMA 1)
+        set(GMX_X86_AVX_128_FMA 1)
+        set(ACCELERATION_STATUS_MESSAGE
+            "Enabling 128-bit AVX Gromacs acceleration (with fused-multiply add), and it will help compiler optimization.")
+
     else()
         # If we are not doing AVX_128, it must be AVX_256...
         set(GMX_CPU_ACCELERATION_X86_AVX_256 1)
         set(GMX_X86_AVX_256 1)
-        if (NOT ACCELERATION_QUIETLY)
-          message(STATUS "Enabling 256-bit AVX Gromacs acceleration, and it will help compiler optimization.")
-        endif()
+        set(ACCELERATION_STATUS_MESSAGE
+            "Enabling 256-bit AVX Gromacs acceleration, and it will help compiler optimization.")
     endif()
 
     # Unfortunately gcc-4.5.2 and gcc-4.6.0 has a bug where they use the wrong datatype for the formal
@@ -887,7 +886,10 @@ elseif(${GMX_CPU_ACCELERATION} STREQUAL "SPARC64_HPC_ACE")
 else()
     gmx_invalid_option_value(GMX_CPU_ACCELERATION)
 endif()
-set(ACCELERATION_QUIETLY TRUE CACHE INTERNAL "")
+gmx_check_if_changed(ACCELERATION_CHANGED GMX_CPU_ACCELERATION)
+if (ACCELERATION_CHANGED AND DEFINED ACCELERATION_STATUS_MESSAGE)
+    message(STATUS "${ACCELERATION_STATUS_MESSAGE}")
+endif()
 
 # Process QM/MM Settings
 if(${GMX_QMMM_PROGRAM} STREQUAL "GAUSSIAN")
@@ -962,9 +964,7 @@ if(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
         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()
 
-    if(NOT "${GMX_FFT_LIBRARY}" STREQUAL "${GMX_FFT_LIBRARY_PREVIOUS_VALUE}")
-        MESSAGE(STATUS "Using external FFT library - FFTW3")
-    endif()
+    set(FFT_STATUS_MESSAGE "Using external FFT library - FFTW3")
 elseif(${GMX_FFT_LIBRARY} STREQUAL "MKL")
     # Intel 11 and up makes life somewhat easy if you just want to use
     # all their stuff. It's not easy if you only want some of their
@@ -1014,18 +1014,17 @@ elseif(${GMX_FFT_LIBRARY} STREQUAL "MKL")
     set(GMX_FFT_MKL 1)
     set(HAVE_LIBMKL 1)
 
-    if(NOT "${GMX_FFT_LIBRARY}" STREQUAL "${GMX_FFT_LIBRARY_PREVIOUS_VALUE}")
-        MESSAGE(STATUS "Using external FFT library - Intel MKL")
-    endif()
+    set(FFT_STATUS_MESSAGE "Using external FFT library - Intel MKL")
 elseif(${GMX_FFT_LIBRARY} STREQUAL "FFTPACK")
     set(GMX_FFT_FFTPACK 1)
-    if(NOT "${GMX_FFT_LIBRARY}" STREQUAL "${GMX_FFT_LIBRARY_PREVIOUS_VALUE}")
-        MESSAGE(STATUS "Using internal FFT library - fftpack")
-    endif()
+    set(FFT_STATUS_MESSAGE "Using internal FFT library - fftpack")
 else(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
     gmx_invalid_option_value(GMX_FFT_LIBRARY)
 endif(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
-set(GMX_FFT_LIBRARY_PREVIOUS_VALUE ${GMX_FFT_LIBRARY} CACHE INTERNAL "Previous value for GMX_FFT_LIBRARY, so that we can detect when it changes.")
+gmx_check_if_changed(FFT_CHANGED GMX_FFT_LIBRARY)
+if (FFT_CHANGED)
+    message(STATUS "${FFT_STATUS_MESSAGE}")
+endif()
 
 # enable threaded fftw3 if we've found it
 if(FFTW3_THREADS OR FFTW3F_THREADS)
@@ -1147,6 +1146,7 @@ gmx_dependent_cache_variable(
     STRING ""
     "NOT GMX_DEFAULT_SUFFIX")
 if (GMX_DEFAULT_SUFFIX)
+  gmx_check_if_changed(SUFFIXES_CHANGED GMX_DEFAULT_SUFFIX)
   set(GMX_BINARY_SUFFIX "")
   set(GMX_LIBS_SUFFIX "")
   if (GMX_LIB_MPI)
@@ -1157,20 +1157,21 @@ if (GMX_DEFAULT_SUFFIX)
     set (GMX_BINARY_SUFFIX "${GMX_BINARY_SUFFIX}_d")
     set (GMX_LIBS_SUFFIX "${GMX_LIBS_SUFFIX}_d")
   endif(GMX_DOUBLE)
-  if (NOT SUFFIX_QUIETLY)
+  if (SUFFIXES_CHANGED)
     message(STATUS "Using default binary suffix: \"${GMX_BINARY_SUFFIX}\"")
     message(STATUS "Using default library suffix: \"${GMX_LIBS_SUFFIX}\"")
-  endif (NOT SUFFIX_QUIETLY)
+  endif ()
 else(GMX_DEFAULT_SUFFIX)
-  if (NOT SUFFIX_QUIETLY)
+  gmx_check_if_changed(SUFFIXES_CHANGED
+                       GMX_DEFAULT_SUFFIX GMX_BINARY_SUFFIX GMX_LIBS_SUFFIX)
+  if (SUFFIXES_CHANGED)
     message(STATUS "Using manually set binary suffix: \"${GMX_BINARY_SUFFIX}\"")
     message(STATUS "Using manually set library suffix: \"${GMX_LIBS_SUFFIX}\"")
-  endif (NOT SUFFIX_QUIETLY)
+  endif ()
 endif(GMX_DEFAULT_SUFFIX)
 if (GMX_BUILD_MDRUN_ONLY)
     set(GMX_LIBS_SUFFIX "_mdrun${GMX_LIBS_SUFFIX}")
 endif ()
-set(SUFFIX_QUIETLY TRUE CACHE INTERNAL "")
 
 ##################################################################
 # Shared library settings
index 1392c0ad39f9ab71e048842e00883b5f9fa748c9..540b403b127b34dba5b57c4d859e52425879ef11 100644 (file)
 #     function_in_library  the name of a function to use in a linking test of that library
 macro(manage_linear_algebra_library name function_in_library)
     set(_library_was_found 0)
-    set(_find_quietly FALSE)
-    set(_user_var_changed FALSE)
-    if(NOT DEFINED GMX_EXTERNAL_${name} OR
-       (GMX_EXTERNAL_${name} AND NOT "${GMX_${name}_USER}" STREQUAL "${GMX_${name}_USER_PREV}"))
-        set(_user_var_changed TRUE)
-    endif()
-    if(DEFINED GMX_EXTERNAL_${name} AND NOT _user_var_changed)
-        set(_find_quietly TRUE)
-    endif()
 
     # We could consider printing status messages at the beginning and
     # end, which would require caching whether the previous provider
@@ -27,8 +18,14 @@ macro(manage_linear_algebra_library name function_in_library)
     # low, so let's solve that one in master branch when we have
     # better CMake gear to support it.
     if(GMX_EXTERNAL_${name} OR NOT DEFINED GMX_EXTERNAL_${name})
-        set(GMX_${name}_USER_PREV ${GMX_${name}_USER} CACHE INTERNAL
-            "Previous value of GMX_${name}_USER (to detect changes)" FORCE)
+        set(_find_quietly FALSE)
+        gmx_check_if_changed(_user_var_changed GMX_${name}_USER)
+        if (NOT DEFINED GMX_EXTERNAL_${name})
+            set(_user_var_changed TRUE)
+        endif()
+        if(DEFINED GMX_EXTERNAL_${name} AND NOT _user_var_changed)
+            set(_find_quietly TRUE)
+        endif()
         set(_message_text)
         # Check for user-specified libraries if external libraries have
         # been specified (which is the default).
@@ -76,7 +73,7 @@ macro(manage_linear_algebra_library name function_in_library)
         # detection succeeded, try to detect ${name} in the CMake
         # detection paths, etc.
         if (NOT _library_was_found)
-            set(${name}_FIND_QUIETLY _find_quietly)
+            set(${name}_FIND_QUIETLY ${_find_quietly})
             # Note that this finds all kinds of system libraries,
             # including Apple's Accelerate Framework (and perhaps MKL for
             # icc < 11).
@@ -99,7 +96,10 @@ macro(manage_linear_algebra_library name function_in_library)
     # Default behaviour is to use a library found on the system or in
     # GROMACS. The user must actively set GMX_${name}_USER if they
     # want to specify a library.
-    set(GMX_${name}_USER "" CACHE BOOL "Use a ${name} library found on the system (OFF), or a ${name} library supplied by the user (any other value, which is a full path to that ${name} library)")
+    gmx_dependent_cache_variable(
+        GMX_${name}_USER
+        "Use a ${name} library found on the system (OFF), or a ${name} library supplied by the user (any other value, which is a full path to that ${name} library)"
+        FILEPATH "" GMX_EXTERNAL_${name})
     mark_as_advanced(GMX_${name}_USER)
 
     if(GMX_EXTERNAL_${name})
index 9387de5273840fda99c959c80733f12e1609e02c..26dc688201662d913ca028f5aec608a3e64a55e4 100644 (file)
@@ -155,3 +155,23 @@ endmacro()
 macro(GMX_DEPENDENT_OPTION NAME DESCRIPTION DEFAULT CONDITIONS)
     gmx_dependent_cache_variable(${NAME} "${DESCRIPTION}" BOOL "${DEFAULT}" "${CONDITIONS}")
 endmacro()
+
+# Checks if one or more cache variables have changed
+#
+# 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.
+# Changes are tracked also across CMake runs.
+function(GMX_CHECK_IF_CHANGED RESULT)
+    set(_result FALSE)
+    foreach (_var ${ARGN})
+        if (NOT "${_var}" STREQUAL "${_var}_PREVIOUS_VALUE")
+            set(_result TRUE)
+        endif()
+        set(${_var}_PREVIOUS_VALUE "${${_var}}" CACHE INTERNAL
+            "Previous value of ${_var} for change tracking")
+    endforeach()
+    set(${RESULT} ${_result} PARENT_SCOPE)
+endfunction()