avoid mdrun crash when rdtscp is not supported
authorMark Abraham <mark.j.abraham@gmail.com>
Fri, 31 Jan 2014 14:06:20 +0000 (15:06 +0100)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Thu, 20 Feb 2014 17:38:11 +0000 (18:38 +0100)
When using rdtscp, mdrun now detects at runtime whether the CPU supports
this instruction and if this is not the case, it issues a fatal error
and instructs the user to recompile mdrun for the compute host. Note
that this will happen rarely, only when cross-compiling from a newer
host for a rather old one.

Additionally, when the user manually picks AVX, we also turn on RDTSCP
as all AVX-capable CPUs support it.

Also made CMake advanced cache option for GMX_USE_RDTSCP. This replaces
the previously hidden GMX_DISTRIBUTABLE_BUILD option.

Fixes #1428

Change-Id: I8bc884ef9ea8ea4661626b60490182ae2b302648

CMakeLists.txt
src/gmxlib/gmx_detect_hardware.c

index b95dab8befb68a310dbd108feac06bc985d044b0..535ec6d3a750075f01cb01dbfab42f9a41a55f78 100644 (file)
@@ -610,10 +610,26 @@ gmx_test_inline_asm_gcc_x86(GMX_X86_GCC_INLINE_ASM)
 
 include(gmxSetBuildInformation)
 gmx_set_build_information()
-if(BUILD_CPU_FEATURES MATCHES "rdtscp" AND NOT GMX_DISTRIBUTABLE_BUILD)
+# Turn on RDTSCP if:
+# - the build system's CPU supports it
+# - the acceleration is set to AVX as all AVX-capable CPUs support AVX (which
+#   at this point means that the user set it).
+# Note: it's better to not use the later set value of GMX_CPU_ACCELERATION because
+# it reflects the system's capability of both compiling and running AVX code.
+# TODO: After merge with 5.0 one could implement a cache variable dependency
+# such that GMX_USE_RDTSCP can change if GMX_CPU_ACCELERATION is changed to AVX
+# after the first cmake pass.
+if (BUILD_CPU_FEATURES MATCHES "rdtscp" OR GMX_CPU_ACCELERATION MATCHES "AVX")
+    set(GMX_USE_RDTSCP_DEFAULT_VALUE ON)
+else()
+    set(GMX_USE_RDTSCP_DEFAULT_VALUE OFF)
+endif()
+option(GMX_USE_RDTSCP "Use RDTSCP for better CPU-based timers (available on recent x86 CPUs; might need to be off when compiling for heterogeneous environments)" ${GMX_USE_RDTSCP_DEFAULT_VALUE})
+mark_as_advanced(GMX_USE_RDTSCP)
+if(GMX_USE_RDTSCP)
     # The timestep counter headers do not include config.h
     add_definitions(-DHAVE_RDTSCP)
-endif(BUILD_CPU_FEATURES MATCHES "rdtscp" AND NOT GMX_DISTRIBUTABLE_BUILD)
+endif()
 
 include(gmxTestFloatFormat)
 gmx_test_float_format(GMX_FLOAT_FORMAT_IEEE754 
index a1c38df268da84ef4507a5764747d906b106d267..a61585739ba5586e3607e5bb9a5df8a029ae1e94 100644 (file)
@@ -45,6 +45,8 @@
 #include "types/commrec.h"
 #include "gmx_fatal.h"
 #include "gmx_fatal_collective.h"
+#include "md_logging.h"
+#include "gmx_cpuid.h"
 #include "smalloc.h"
 #include "gpu_utils.h"
 #include "statutil.h"
@@ -210,6 +212,40 @@ static void parse_gpu_id_csv_string(const char *idstr, int *nid, int *idlist)
     gmx_incons("Not implemented yet");
 }
 
+/* Give a suitable fatal error or warning if the build configuration
+   and runtime CPU do not match. */
+static void
+check_use_of_rdtscp_on_this_cpu(FILE                *fplog,
+                                const t_commrec     *cr,
+                                const gmx_hw_info_t *hwinfo)
+{
+    gmx_bool bCpuHasRdtscp, bBinaryUsesRdtscp;
+#ifdef HAVE_RDTSCP
+    bBinaryUsesRdtscp = TRUE;
+#else
+    bBinaryUsesRdtscp = FALSE;
+#endif
+
+    bCpuHasRdtscp = gmx_cpuid_feature(hwinfo->cpuid_info, GMX_CPUID_FEATURE_X86_RDTSCP);
+
+    if (!bCpuHasRdtscp && bBinaryUsesRdtscp)
+    {
+        gmx_fatal(FARGS, "The %s executable was compiled to use the rdtscp CPU instruction. "
+                  "However, this is not supported by the current hardware and continuing would lead to a crash. "
+                  "Please rebuild GROMACS with the GMX_USE_RDTSCP=OFF CMake option.",
+                  ShortProgram());
+    }
+
+    if (bCpuHasRdtscp && !bBinaryUsesRdtscp)
+    {
+        md_print_warn(cr, fplog, "The current CPU can measure timings more accurately than the code in\n"
+                      "%s was configured to use. This might affect your simulation\n"
+                      "speed as accurate timings are needed for load-balancing.\n"
+                      "Please consider rebuilding %s with the GMX_USE_RDTSCP=OFF CMake option.\n",
+                      ShortProgram(), ShortProgram());
+    }
+}
+
 void gmx_check_hw_runconf_consistency(FILE *fplog,
                                       const gmx_hw_info_t *hwinfo,
                                       const t_commrec *cr,
@@ -252,6 +288,8 @@ void gmx_check_hw_runconf_consistency(FILE *fplog,
              the case! Might not hurt to add an extra check over MPI. */
     gmx_cpuid_acceleration_check(hwinfo->cpuid_info, fplog, SIMMASTER(cr));
 
+    check_use_of_rdtscp_on_this_cpu(fplog, cr, hwinfo);
+
     /* NOTE: this print is only for and on one physical node */
     print_gpu_detection_stats(fplog, &hwinfo->gpu_info, cr);