]> Savannah Git Hosting - gnulib.git/commitdiff
nproc: support nested OMP_NUM_THREADS, and OMP_THREAD_LIMIT
authorPádraig Brady <P@draigBrady.com>
Tue, 21 Feb 2017 04:26:35 +0000 (20:26 -0800)
committerPádraig Brady <P@draigBrady.com>
Sun, 26 Feb 2017 11:38:20 +0000 (03:38 -0800)
* lib/nproc.c (parse_omp_threads): A new function refactored
from num_processors() to support parsing both of the
above environment variables.
(num_processors): Prefer using omp_get_num_threads() with [_OPENMP]
to accurately reflect the current OpenMP nesting level.
Also support the OMP_THREAD_LIMIT environment variable
to limit the max value determined from OMP_NUM_THREADS.
* modules/nproc: Depend on minmax header.
Suggested by Oliver Heimlich.

ChangeLog
lib/nproc.c
modules/nproc

index c46dba74ad41be1e8251b4524f8c1fc3af00a196..318b50b76e1b07f7e2ba3c1cbed532dd7e7268a2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2017-02-26  Pádraig Brady  <P@draigBrady.com>
+
+       nproc: support nested OMP_NUM_THREADS, and OMP_THREAD_LIMIT
+       * lib/nproc.c (parse_omp_threads): A new function refactored
+       from num_processors() to support parsing both of the
+       above environment variables.
+       (num_processors): Prefer using omp_get_num_threads() with [_OPENMP]
+       to accurately reflect the current OpenMP nesting level.
+       Also support the OMP_THREAD_LIMIT environment variable
+       to limit the max value determined from OMP_NUM_THREADS.
+       * modules/nproc: Depend on minmax header.
+       Suggested by Oliver Heimlich.
+
 2017-02-25  Bruno Haible  <bruno@clisp.org>
 
        maintainer-makefile: Fix AC_PROG_SED with autoconf cache.
index 9053d75c52a221f9a9e96a37e0eff303380eaedf..3d9007b1aaca5fc9ef3e82cd09f5cc86cea34e74 100644 (file)
 # include <windows.h>
 #endif
 
+#if defined(_OPENMP)
+# include <omp.h>
+#endif
+
 #include "c-ctype.h"
 
+#include "minmax.h"
+
 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
 
 /* Return the number of processors available to the current process, based
@@ -196,35 +202,67 @@ num_processors_via_affinity_mask (void)
   return 0;
 }
 
+/* Parse OMP environment variables without dependence on OMP.
+   Return > 0 for valid values.  */
+static unsigned long int
+parse_omp_threads (char const* threads)
+{
+  unsigned long int ret = 0;
+
+  if (threads == NULL)
+    return ret;
+
+  /* The OpenMP spec says that the value assigned to the environment variables
+     "may have leading and trailing white space".  */
+  while (*threads != '\0' && c_isspace (*threads))
+    threads++;
+
+  /* Convert it from decimal to 'unsigned long'.  */
+  if (c_isdigit (*threads))
+    {
+      char *endptr = NULL;
+      unsigned long int value = strtoul (threads, &endptr, 10);
+
+      if (endptr != NULL)
+        {
+          while (*endptr != '\0' && c_isspace (*endptr))
+            endptr++;
+          if (*endptr == '\0')
+            return (value > 0 ? value : 1);
+          /* Also accept the first value in a nesting level,
+             since we can't determine the nesting level from env vars.  */
+          else if (*endptr == ',')
+            return (value > 0 ? value : 1);
+        }
+    }
+
+  return ret;
+}
+
 unsigned long int
 num_processors (enum nproc_query query)
 {
   if (query == NPROC_CURRENT_OVERRIDABLE)
     {
-      /* Test the environment variable OMP_NUM_THREADS, recognized also by all
-         programs that are based on OpenMP.  The OpenMP spec says that the
-         value assigned to the environment variable "may have leading and
-         trailing white space". */
-      const char *envvalue = getenv ("OMP_NUM_THREADS");
+      unsigned long int omp_env_threads;
+      unsigned long int omp_env_limit;
+
+/* If OPENMP is enabled with AC_OPENMP, then use OPENMP to
+   get the number of threads for the current nesting level.  */
+#if defined(_OPENMP)
+      return omp_get_num_threads ();
+#endif
 
-      if (envvalue != NULL)
+      /* Honor the OpenMP environment variables, recognized also by all
+         programs that are based on OpenMP.  */
+      omp_env_threads = parse_omp_threads (getenv ("OMP_NUM_THREADS"));
+      if (omp_env_threads)
         {
-          while (*envvalue != '\0' && c_isspace (*envvalue))
-            envvalue++;
-          /* Convert it from decimal to 'unsigned long'.  */
-          if (c_isdigit (*envvalue))
-            {
-              char *endptr = NULL;
-              unsigned long int value = strtoul (envvalue, &endptr, 10);
-
-              if (endptr != NULL)
-                {
-                  while (*endptr != '\0' && c_isspace (*endptr))
-                    endptr++;
-                  if (*endptr == '\0')
-                    return (value > 0 ? value : 1);
-                }
-            }
+          omp_env_limit = parse_omp_threads (getenv ("OMP_THREADS_LIMIT"));
+          if (omp_env_limit > 1)
+            omp_env_threads = MIN (omp_env_threads, omp_env_limit);
+
+          return omp_env_threads;
         }
 
       query = NPROC_CURRENT;
index 2cbf04d92bca186600a07cdc24a6fc30202cac19..525957942793cb7f7ea751c3f80fa2027696f354 100644 (file)
@@ -9,6 +9,7 @@ m4/nproc.m4
 Depends-on:
 c-ctype
 extensions
+minmax
 unistd
 
 configure.ac: