Update affinity checking for Intel compiler
authorErik Lindahl <erik@kth.se>
Thu, 7 Jul 2016 18:29:33 +0000 (20:29 +0200)
committerErik Lindahl <erik.lindahl@gmail.com>
Fri, 8 Jul 2016 17:16:41 +0000 (19:16 +0200)
Since release 2013, the Intel compiler no longer sets
OpenMP affinity by default according to intel docs. This
means the code that tried to disable it by setting
environment variables no longer had any effect (and we
likely have not checked it the last few years). In
addition, it is not ideal behaviour in a library either to
assume that no other code has executed OpenMP prior to a call
or to set environment variables that influence other code
execution too. However, we will still disable Gromacs' own
thread affinity if it has been set by the user or calling code.

Change-Id: I57a952766e87a35483f1960b349f7c30d5b85f24

src/gromacs/utility/gmxomp.cpp
src/gromacs/utility/gmxomp.h

index a1f92b3fc5e1d19d1bb23e47b6a4d9d8c7d0ef74..1b3ceccc129a4a15b7fa76e8b7360ba9d2d0aaeb 100644 (file)
@@ -136,41 +136,19 @@ gmx_bool gmx_omp_check_thread_affinity(char **message)
     const char *const kmp_env         = getenv("KMP_AFFINITY");
     const bool        bKmpAffinitySet = (kmp_env != NULL);
 
-    /* disable Intel OpenMP affinity if neither KMP_AFFINITY nor
-     * GOMP_CPU_AFFINITY is set (Intel uses the GNU env. var as well) */
-    if (!bKmpAffinitySet && !bGompCpuAffinitySet)
-    {
-        int retval;
-
-#ifdef _MSC_VER
-        /* Windows not POSIX */
-        retval = _putenv_s("KMP_AFFINITY", "disabled");
-#else
-        /* POSIX */
-        retval = setenv("KMP_AFFINITY", "disabled", 0);
-#endif  /* _MSC_VER */
-
-        if (debug)
-        {
-            fprintf(debug, "Disabling Intel OpenMP affinity by setting the KMP_AFFINITY=disabled env. var.\n");
-        }
-
-        if (retval != 0)
-        {
-            gmx_warning("Disabling Intel OpenMp affinity setting failed!");
-        }
-    }
-
-    /* turn off internal pinning KMP_AFFINITY != "disabled" */
-    if (bKmpAffinitySet && (gmx_strncasecmp(kmp_env, "disabled", 8) != 0))
+    // turn off internal pinning if KMP_AFFINITY is set but does not contain
+    // the settings 'disabled' or 'none'.
+    if (bKmpAffinitySet &&
+        (strstr(kmp_env, "disabled") == NULL) &&
+        (strstr(kmp_env, "none") == NULL))
     {
         try
         {
             std::string buf = gmx::formatString(
                         "NOTE: KMP_AFFINITY set, will turn off %s internal affinity\n"
                         "      setting as the two can conflict and cause performance degradation.\n"
-                        "      To keep using the %s internal affinity setting, set the\n"
-                        "      KMP_AFFINITY=disabled environment variable.",
+                        "      To keep using the %s internal affinity setting, unset the\n"
+                        "      KMP_AFFINITY environment variable or set it to 'none' or 'disabled'.",
                         programName, programName);
             *message = gmx_strdup(buf.c_str());
         }
index 64cf0c3689a940d948ef7f3d2d4bbbbdd5bb9b15..471563307b22db6aff1a9ffe8ac8b0797a6700cf 100644 (file)
@@ -115,20 +115,9 @@ void gmx_omp_set_num_threads(int num_threads);
  * \param[out] message  Receives the message to be shown to the user.
  * \returns `true` if we can set thread affinity ourselves.
  *
- * While GNU OpenMP does not set affinity by default, the Intel OpenMP library
- * does.  This conflicts with the internal affinity (especially thread-MPI)
- * setting, results in incorrectly locked threads, and causes dreadful performance.
- *
  * The KMP_AFFINITY environment variable is used by Intel, GOMP_CPU_AFFINITY
  * by the GNU compilers (Intel also honors it well).  If any of the variables
  * is set, we should honor it and disable the internal pinning.
- * When using Intel OpenMP, we will disable affinity if the user did not set it
- * manually through one of the aforementioned environment variables.
- *
- * Note that the Intel OpenMP affinity disabling will only take effect if this
- * function is called before the OpenMP library gets initialized, which happens
- * when the first call is made into a compilation unit that contains OpenMP
- * pragmas.
  *
  * If this function returns `false`, the caller is responsible to disable the
  * pinning, show the message from \p *message to the user, and free the memory