From: Bruno Haible Date: Tue, 9 Apr 2019 19:02:35 +0000 (+0200) Subject: openmp: Add workaround for 32-bit programs on AIX. X-Git-Tag: v1.0~4988 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=f6225ebbe70d592453edcb47f9238eb4336edca9;p=gnulib.git openmp: Add workaround for 32-bit programs on AIX. * lib/omp.in.h: New file. * lib/omp-init.c: New file, based on lib/nproc.c. * m4/omp_h.m4: New file. * modules/openmp (Files): Add them. (Depends-on): Add include_next, c-ctype, setenv. (configure.ac): Invoke gl_OMP_H. (Makefile.am): Add rules to create omp.h and compile omp-init.c. (Include): Mention . --- diff --git a/ChangeLog b/ChangeLog index 035e411552..87d95ed993 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2019-04-09 Bruno Haible + + openmp: Add workaround for 32-bit programs on AIX. + * lib/omp.in.h: New file. + * lib/omp-init.c: New file, based on lib/nproc.c. + * m4/omp_h.m4: New file. + * modules/openmp (Files): Add them. + (Depends-on): Add include_next, c-ctype, setenv. + (configure.ac): Invoke gl_OMP_H. + (Makefile.am): Add rules to create omp.h and compile omp-init.c. + (Include): Mention . + 2019-04-09 Bruno Haible nproc: Fix return value for privileged processes. diff --git a/lib/omp-init.c b/lib/omp-init.c new file mode 100644 index 0000000000..f849067374 --- /dev/null +++ b/lib/omp-init.c @@ -0,0 +1,88 @@ +/* Initialize OpenMP. + + Copyright (C) 2017-2019 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . */ + +#include + +/* Specification. */ +#include + +#include + +#include "c-ctype.h" + +#if defined _AIX + +/* Parse OMP environment variables without dependence on OMP. + Return 0 for invalid 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 positive 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; + /* 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; + } + } + + return ret; +} + +#endif + +void +openmp_init (void) +{ + /* On AIX 7.2, in 32-bit mode, use of OpenMP on machines with 64 or 128 + processors makes the program fail with an error message + "1587-120 SMP runtime library error. Memory allocation failed when creating thread number 62.". + The workaround is to tell the OpenMP library to create fewer than 62 + threads. This can be done through the OMP_THREAD_LIMIT environment + variable. */ +#if defined _AIX + if (sizeof (long) == sizeof (int)) + { + /* Ensure that OMP_THREAD_LIMIT has a value <= 32. */ + unsigned long int omp_env_limit = + parse_omp_threads (getenv ("OMP_THREAD_LIMIT")); + + if (!(omp_env_limit > 0 && omp_env_limit <= 32)) + setenv ("OMP_THREAD_LIMIT", "32", 1); + } +#endif +} diff --git a/lib/omp.in.h b/lib/omp.in.h new file mode 100644 index 0000000000..46d2587a74 --- /dev/null +++ b/lib/omp.in.h @@ -0,0 +1,43 @@ +/* OpenMP declarations. + + Copyright (C) 2019 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#ifndef _@GUARD_PREFIX@_OMP_H + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_OMP_H@ + +#ifndef _@GUARD_PREFIX@_OMP_H +#define _@GUARD_PREFIX@_OMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializes environment variables necessary for OpenMP. */ +extern void openmp_init (void); + +#ifdef __cplusplus +} +#endif + +#endif /* _@GUARD_PREFIX@_OMP_H */ +#endif /* _@GUARD_PREFIX@_OMP_H */ diff --git a/m4/omp_h.m4 b/m4/omp_h.m4 new file mode 100644 index 0000000000..87905bb304 --- /dev/null +++ b/m4/omp_h.m4 @@ -0,0 +1,10 @@ +# omp_h.m4 serial 1 +dnl Copyright (C) 2019 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_OMP_H], +[ + gl_NEXT_HEADERS([omp.h]) +]) diff --git a/modules/openmp b/modules/openmp index 76f012d2d6..ef8e605fe8 100644 --- a/modules/openmp +++ b/modules/openmp @@ -2,15 +2,43 @@ Description: Detection of OpenMP support. Files: +lib/omp.in.h +lib/omp-init.c +m4/omp_h.m4 Depends-on: +include_next +c-ctype +setenv configure.ac: AC_OPENMP +gl_OMP_H Makefile.am: +BUILT_SOURCES += omp.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +omp.h: omp.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ + $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|${gl_include_guard_prefix}|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_OMP_H''@|$(NEXT_OMP_H)|g' \ + < $(srcdir)/omp.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += omp.h omp.h-t +lib_SOURCES += omp-init.c Include: +#ifdef _OPENMP +# include +#endif Link: $(OPENMP_CFLAGS)