From: Pádraig Brady Date: Tue, 21 Feb 2017 04:26:35 +0000 (-0800) Subject: nproc: support nested OMP_NUM_THREADS, and OMP_THREAD_LIMIT X-Git-Tag: v1.0~6348 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=3f61a6d1c24ba50e31edb2200f7400d0b029d4cc;p=gnulib.git 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. --- diff --git a/ChangeLog b/ChangeLog index c46dba74ad..318b50b76e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2017-02-26 Pádraig Brady + + 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 maintainer-makefile: Fix AC_PROG_SED with autoconf cache. diff --git a/lib/nproc.c b/lib/nproc.c index 9053d75c52..3d9007b1aa 100644 --- a/lib/nproc.c +++ b/lib/nproc.c @@ -54,8 +54,14 @@ # include #endif +#if defined(_OPENMP) +# include +#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; diff --git a/modules/nproc b/modules/nproc index 2cbf04d92b..5259579427 100644 --- a/modules/nproc +++ b/modules/nproc @@ -9,6 +9,7 @@ m4/nproc.m4 Depends-on: c-ctype extensions +minmax unistd configure.ac: