bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
From: Bruno Haible <bruno@clisp.org>
To: bug-gnulib@gnu.org
Subject: openmp: add workaround for 32-bit programs on AIX
Date: Tue, 09 Apr 2019 21:03:13 +0200	[thread overview]
Message-ID: <1916834.s440QdyOn8@omega> (raw)

On AIX 7.2, gettext's msgmerge, compiled in 32-bit mode, crashes with this error
message:

1587-120 SMP runtime library error. Memory allocation failed when creating thread number 62.

Apparently, because the machine has 64 or 128 CPUs, the AIX OpenMP library
attempts to allocate 64 or 128 threads, and this fails, probably because the
address space is exhausted by the stack space needed for so many threads.

One option would be to disable OpenMP in this situation; the other one is to
limit the number of threads, by setting the environment variable
OMP_NUM_THREADS or OMP_THREAD_LIMIT. I prefer the latter one.

The problem and fix are not specific to msgmerge, but apply to all
programs that use OpenMP. Therefore it has its place in gnulib.


2019-04-09  Bruno Haible  <bruno@clisp.org>

	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 <omp.h>.

================================ lib/omp.in.h ================================
/* 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 <https://www.gnu.org/licenses/>.  */

#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 */
=============================== lib/omp-init.c ===============================
/* 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 <https://www.gnu.org/licenses/>.  */

#include <config.h>

/* Specification.  */
#include <omp.h>

#include <stdlib.h>

#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
}
================================ m4/omp_h.m4 ================================
# 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 76f012d..ef8e605 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 <omp.h> 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 <omp.h>
+#endif
 
 Link:
 $(OPENMP_CFLAGS)



             reply	other threads:[~2019-04-09 19:05 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-09 19:03 Bruno Haible [this message]
2019-04-12 22:09 ` openmp: add workaround for 32-bit programs on AIX Bruno Haible
2019-04-13  9:04 ` Bruno Haible

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://lists.gnu.org/mailman/listinfo/bug-gnulib

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1916834.s440QdyOn8@omega \
    --to=bruno@clisp.org \
    --cc=bug-gnulib@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).