* [gomp5] Implement omp_[sg]et_affinity_format, omp_{capture,display}_affinity, OMP_DISPLAY_AFFINITY and OMP_AFFINITY_FORMAT
@ 2018-05-23 14:59 Jakub Jelinek
0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2018-05-23 14:59 UTC (permalink / raw)
To: gcc-patches
Hi!
The following patch implements functions and env vars to query and display
affinity related information.
Tested on x86_64-linux, committed to gomp-5.0 branch.
2018-05-23 Jakub Jelinek <jakub@redhat.com>
* configure.ac (HAVE_UNAME, HAVE_GETHOSTNAME, HAVE_GETPID): Add
new tests.
* configure.tgt: Add -DUSING_INITIAL_EXEC_TLS to XCFLAGS for Linux.
* Makefile.am (libgomp_la_SOURCES): Add affinity-fmt.c.
* libgomp.map (OMP_5.0): Export omp_{capture,display}_affinity{,_},
and omp_[gs]et_affinity_format{,_}.
* libgomp.h (gomp_display_affinity_var, gomp_affinity_format_var,
gomp_affinity_format_len): Declare.
(GOMP_NEEDS_THREAD_HANDLE): Define if needed.
(struct gomp_thread): Add handle field if GOMP_NEEDS_THREAD_HANDLE is
defined.
(gomp_display_affinity_place): Declare.
(gomp_set_affinity_format, gomp_display_string): Likewise.
(gomp_thread_handle): New typedef.
(gomp_display_affinity, gomp_display_affinity_thread): Declare.
(gomp_thread_self, gomp_thread_to_pthread_t): New inline functions.
* affinity-fmt.c: New file.
* affinity.c (gomp_display_affinity_place): New function.
* config/linux/affinity.c (gomp_display_affinity_place): New function.
* env.c (gomp_display_affinity_var, gomp_affinity_format_var,
gomp_affinity_format_len): New variables.
(handle_omp_display_env): Print OMP_DISPLAY_AFFINITY and
OMP_AFFINITY_FORMAT.
(initialize_env): Handle OMP_DISPLAY_AFFINITY and OMP_AFFINITY_FORMAT
env vars.
* fortran.c: Include stdio.h and string.h.
(omp_set_affinity_format_, omp_get_affinity_format_,
omp_display_affinity_, omp_capture_affinity_): New functions.
* omp.h.in (omp_set_affinity_format, omp_get_affinity_format,
omp_display_affinity, omp_capture_affinity): Declare.
* omp_lib.f90.in (omp_set_affinity_format, omp_get_affinity_format,
omp_display_affinity, omp_capture_affinity): Add new interfaces.
* omp_lib.h.in (omp_set_affinity_format, omp_get_affinity_format,
omp_display_affinity, omp_capture_affinity): New externs.
* team.c (struct gomp_thread_start_data): Add handle field.
(gomp_team_start): Handle OMP_DISPLAY_AFFINITY env var.
* configure: Regenerated.
* config.h.in: Regenerated.
* Makefile.in: Regenerated.
* testsuite/libgomp.c-c++-common/display-affinity-1.c: New test.
* testsuite/libgomp.fortran/display-affinity-1.f90: New test.
--- libgomp/configure.ac.jj 2018-04-30 13:19:48.198834863 +0200
+++ libgomp/configure.ac 2018-05-22 14:15:24.425935883 +0200
@@ -266,6 +266,41 @@ if test $ac_cv_func_clock_gettime = no;
[Define to 1 if you have the `clock_gettime' function.])])
fi
+# Check for uname.
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [#include <string.h>
+ #include <stdlib.h>
+ #include <sys/utsname.h>],
+ [struct utsname buf;
+ volatile size_t len = 0;
+ if (!uname (buf))
+ len = strlen (buf.nodename);])],
+ AC_DEFINE(HAVE_UNAME, 1,
+[ Define if uname is supported and struct utsname has nodename field.]))
+
+# Check for gethostname.
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [#include <unistd.h>],
+ [
+changequote(,)dnl
+ char buf[256];
+ if (gethostname (buf, sizeof (buf) - 1) == 0)
+ buf[255] = '\0';
+changequote([,])dnl
+ ])],
+ AC_DEFINE(HAVE_GETHOSTNAME, 1,
+[ Define if gethostname is supported.]))
+
+# Check for getpid.
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [#include <unistd.h>],
+ [int pid = getpid ();])],
+ AC_DEFINE(HAVE_GETPID, 1,
+[ Define if getpid is supported.]))
+
# See if we support thread-local storage.
GCC_CHECK_TLS
--- libgomp/configure.tgt.jj 2017-05-04 15:04:53.677371383 +0200
+++ libgomp/configure.tgt 2018-05-23 14:34:01.875414884 +0200
@@ -18,7 +18,7 @@ if test $gcc_cv_have_tls = yes ; then
;;
*-*-linux* | *-*-gnu*)
- XCFLAGS="${XCFLAGS} -ftls-model=initial-exec"
+ XCFLAGS="${XCFLAGS} -ftls-model=initial-exec -DUSING_INITIAL_EXEC_TLS"
;;
*-*-rtems*)
--- libgomp/Makefile.am.jj 2017-05-04 15:04:53.679371358 +0200
+++ libgomp/Makefile.am 2018-05-21 17:21:48.717963247 +0200
@@ -63,7 +63,8 @@ libgomp_la_SOURCES = alloc.c atomic.c ba
parallel.c sections.c single.c task.c team.c work.c lock.c mutex.c \
proc.c sem.c bar.c ptrlock.c time.c fortran.c affinity.c target.c \
splay-tree.c libgomp-plugin.c oacc-parallel.c oacc-host.c oacc-init.c \
- oacc-mem.c oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c
+ oacc-mem.c oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c \
+ affinity-fmt.c
include $(top_srcdir)/plugin/Makefrag.am
--- libgomp/libgomp.map.jj 2018-04-30 13:19:48.356834924 +0200
+++ libgomp/libgomp.map 2018-05-23 14:08:47.362850982 +0200
@@ -164,6 +164,18 @@ OMP_4.5 {
omp_target_disassociate_ptr;
} OMP_4.0;
+OMP_5.0 {
+ global:
+ omp_capture_affinity;
+ omp_capture_affinity_;
+ omp_display_affinity;
+ omp_display_affinity_;
+ omp_get_affinity_format;
+ omp_get_affinity_format_;
+ omp_set_affinity_format;
+ omp_set_affinity_format_;
+} OMP_4.5;
+
GOMP_1.0 {
global:
GOMP_atomic_end;
--- libgomp/libgomp.h.jj 2018-04-30 13:21:05.440865896 +0200
+++ libgomp/libgomp.h 2018-05-23 16:20:40.149705792 +0200
@@ -365,6 +365,9 @@ extern void **gomp_places_list;
extern unsigned long gomp_places_list_len;
extern unsigned int gomp_num_teams_var;
extern int gomp_debug_var;
+extern bool gomp_display_affinity_var;
+extern char *gomp_affinity_format_var;
+extern size_t gomp_affinity_format_len;
extern int goacc_device_num;
extern char *goacc_device_type;
@@ -613,6 +616,19 @@ struct gomp_thread
/* User pthread thread pool */
struct gomp_thread_pool *thread_pool;
+
+#if defined(LIBGOMP_USE_PTHREADS) \
+ && (!defined(HAVE_TLS) \
+ || !defined(__GLIBC__) \
+ || !defined(USING_INITIAL_EXEC_TLS))
+ /* pthread_t of the thread containing this gomp_thread.
+ On Linux when using initial-exec TLS,
+ (typeof (pthread_t)) gomp_thread () - pthread_self ()
+ is constant in all threads, so we can optimize and not
+ store it. */
+#define GOMP_NEEDS_THREAD_HANDLE 1
+ pthread_t handle;
+#endif
};
@@ -709,6 +725,24 @@ extern bool gomp_affinity_finalize_place
extern bool gomp_affinity_init_level (int, unsigned long, bool);
extern void gomp_affinity_print_place (void *);
extern void gomp_get_place_proc_ids_8 (int, int64_t *);
+extern void gomp_display_affinity_place (char *, size_t, size_t *, int);
+
+/* affinity-fmt.c */
+
+extern void gomp_set_affinity_format (const char *, size_t);
+extern void gomp_display_string (char *, size_t, size_t *, const char *,
+ size_t);
+#ifdef LIBGOMP_USE_PTHREADS
+typedef pthread_t gomp_thread_handle;
+#else
+typedef struct {} gomp_thread_handle;
+#endif
+extern size_t gomp_display_affinity (char *, size_t, const char *,
+ gomp_thread_handle,
+ struct gomp_team_state *, unsigned int);
+extern void gomp_display_affinity_thread (gomp_thread_handle,
+ struct gomp_team_state *,
+ unsigned int) __attribute__((cold));
/* iter.c */
@@ -1131,4 +1165,42 @@ task_to_priority_node (enum priority_que
return (struct priority_node *) ((char *) task
+ priority_queue_offset (type));
}
+
+#ifdef LIBGOMP_USE_PTHREADS
+static inline gomp_thread_handle
+gomp_thread_self (void)
+{
+ return pthread_self ();
+}
+
+static inline gomp_thread_handle
+gomp_thread_to_pthread_t (struct gomp_thread *thr)
+{
+ struct gomp_thread *this_thr = gomp_thread ();
+ if (thr == this_thr)
+ return pthread_self ();
+#ifdef GOMP_NEEDS_THREAD_HANDLE
+ return thr->handle;
+#else
+ /* On Linux with initial-exec TLS, the pthread_t of the thread containing
+ thr can be computed from thr, this_thr and pthread_self (),
+ as the distance between this_thr and pthread_self () is constant. */
+ return pthread_self () + ((uintptr_t) thr - (uintptr_t) this_thr);
+#endif
+}
+#else
+static inline gomp_thread_handle
+gomp_thread_self (void)
+{
+ return (gomp_thread_handle) {};
+}
+
+static inline gomp_thread_handle
+gomp_thread_to_pthread_t (struct gomp_thread *thr)
+{
+ (void) thr;
+ return gomp_thread_self ();
+}
+#endif
+
#endif /* LIBGOMP_H */
--- libgomp/affinity-fmt.c.jj 2018-05-21 17:29:19.988327335 +0200
+++ libgomp/affinity-fmt.c 2018-05-23 16:22:32.610813049 +0200
@@ -0,0 +1,473 @@
+/* Copyright (C) 2018 Free Software Foundation, Inc.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp 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, or (at your option)
+ any later version.
+
+ Libgomp 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.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "libgomp.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_UNAME
+#include <sys/utsname.h>
+#endif
+
+void
+gomp_set_affinity_format (const char *format, size_t len)
+{
+ if (len < gomp_affinity_format_len)
+ memcpy (gomp_affinity_format_var, format, len);
+ else
+ {
+ char *p;
+ if (gomp_affinity_format_len)
+ p = gomp_realloc (gomp_affinity_format_var, len + 1);
+ else
+ p = gomp_malloc (len + 1);
+ memcpy (p, format, len);
+ gomp_affinity_format_var = p;
+ gomp_affinity_format_len = len + 1;
+ }
+ gomp_affinity_format_var[len] = '\0';
+}
+
+void
+omp_set_affinity_format (const char *format)
+{
+ gomp_set_affinity_format (format, strlen (format));
+}
+
+size_t
+omp_get_affinity_format (char *buffer, size_t size)
+{
+ size_t len = strlen (gomp_affinity_format_var);
+ if (size)
+ {
+ if (len < size)
+ memcpy (buffer, gomp_affinity_format_var, len + 1);
+ else
+ {
+ memcpy (buffer, gomp_affinity_format_var, size - 1);
+ buffer[size - 1] = '\0';
+ }
+ }
+ return len;
+}
+
+void
+gomp_display_string (char *buffer, size_t size, size_t *ret,
+ const char *str, size_t len)
+{
+ size_t r = *ret;
+ if (size && r < size)
+ {
+ size_t l = len;
+ if (size - r < len)
+ l = size - r;
+ memcpy (buffer + r, str, l);
+ }
+ *ret += len;
+ if (__builtin_expect (r > *ret, 0))
+ gomp_fatal ("overflow in omp_capture_affinity");
+}
+
+static void
+gomp_display_repeat (char *buffer, size_t size, size_t *ret,
+ char c, size_t len)
+{
+ size_t r = *ret;
+ if (size && r < size)
+ {
+ size_t l = len;
+ if (size - r < len)
+ l = size - r;
+ memset (buffer + r, c, l);
+ }
+ *ret += len;
+ if (__builtin_expect (r > *ret, 0))
+ gomp_fatal ("overflow in omp_capture_affinity");
+}
+
+static void
+gomp_display_num (char *buffer, size_t size, size_t *ret,
+ bool zero, bool right, size_t sz, char *buf)
+{
+ size_t l = strlen (buf);
+ if (sz == (size_t) -1 || l >= sz)
+ {
+ gomp_display_string (buffer, size, ret, buf, l);
+ return;
+ }
+ if (zero)
+ {
+ if (buf[0] == '-')
+ gomp_display_string (buffer, size, ret, buf, 1);
+ else if (buf[0] == '0' && buf[1] == 'x')
+ gomp_display_string (buffer, size, ret, buf, 2);
+ gomp_display_repeat (buffer, size, ret, '0', sz - l);
+ if (buf[0] == '-')
+ gomp_display_string (buffer, size, ret, buf + 1, l - 1);
+ else if (buf[0] == '0' && buf[1] == 'x')
+ gomp_display_string (buffer, size, ret, buf + 2, l - 2);
+ else
+ gomp_display_string (buffer, size, ret, buf, l);
+ }
+ else if (right)
+ {
+ gomp_display_repeat (buffer, size, ret, ' ', sz - l);
+ gomp_display_string (buffer, size, ret, buf, l);
+ }
+ else
+ {
+ gomp_display_string (buffer, size, ret, buf, l);
+ gomp_display_repeat (buffer, size, ret, ' ', sz - l);
+ }
+}
+
+static void
+gomp_display_int (char *buffer, size_t size, size_t *ret,
+ bool zero, bool right, size_t sz, int num)
+{
+ char buf[3 * sizeof (int) + 2];
+ sprintf (buf, "%d", num);
+ gomp_display_num (buffer, size, ret, zero, right, sz, buf);
+}
+
+static void
+gomp_display_string_len (char *buffer, size_t size, size_t *ret,
+ bool right, size_t sz, char *str, size_t len)
+{
+ if (sz == (size_t) -1 || len >= sz)
+ {
+ gomp_display_string (buffer, size, ret, str, len);
+ return;
+ }
+
+ if (right)
+ {
+ gomp_display_repeat (buffer, size, ret, ' ', sz - len);
+ gomp_display_string (buffer, size, ret, str, len);
+ }
+ else
+ {
+ gomp_display_string (buffer, size, ret, str, len);
+ gomp_display_repeat (buffer, size, ret, ' ', sz - len);
+ }
+}
+
+static void
+gomp_display_hostname (char *buffer, size_t size, size_t *ret,
+ bool right, size_t sz)
+{
+#ifdef HAVE_GETHOSTNAME
+ {
+ char buf[256];
+ char *b = buf;
+ size_t len = 256;
+ do
+ {
+ b[len - 1] = '\0';
+ if (gethostname (b, len - 1) == 0)
+ {
+ size_t l = strlen (b);
+ if (l < len - 1)
+ {
+ gomp_display_string_len (buffer, size, ret,
+ right, sz, b, l);
+ if (b != buf)
+ free (b);
+ return;
+ }
+ }
+ if (len == 1048576)
+ break;
+ len = len * 2;
+ if (len == 512)
+ b = gomp_malloc (len);
+ else
+ b = gomp_realloc (b, len);
+ }
+ while (1);
+ if (b != buf)
+ free (b);
+ }
+#endif
+#ifdef HAVE_UNAME
+ {
+ struct utsname buf;
+ if (uname (&buf) == 0)
+ {
+ gomp_display_string_len (buffer, size, ret, right, sz,
+ buf.nodename, strlen (buf.nodename));
+ return;
+ }
+ }
+#endif
+ gomp_display_string_len (buffer, size, ret, right, sz, "node", 4);
+}
+
+struct affinity_types_struct {
+ char long_str[18];
+ char long_len;
+ char short_c; };
+
+static struct affinity_types_struct affinity_types[] =
+{
+#define AFFINITY_TYPE(l, s) \
+ { #l, sizeof (#l) - 1, s }
+ AFFINITY_TYPE (thread_level, 'L'),
+ AFFINITY_TYPE (thread_num, 'n'),
+ AFFINITY_TYPE (host, 'h'),
+ AFFINITY_TYPE (process_id, 'P'),
+ AFFINITY_TYPE (thread_identifier, 'T'),
+ AFFINITY_TYPE (num_threads, 'N'),
+ AFFINITY_TYPE (ancestor_tnum, 'A'),
+ AFFINITY_TYPE (thread_affinity, 'a')
+#undef AFFINITY_TYPE
+};
+
+size_t
+gomp_display_affinity (char *buffer, size_t size,
+ const char *format, gomp_thread_handle handle,
+ struct gomp_team_state *ts, unsigned int place)
+{
+ size_t ret = 0;
+ do
+ {
+ const char *p = strchr (format, '%');
+ bool zero = false;
+ bool right = false;
+ size_t sz = -1;
+ char c;
+ int val;
+ if (p == NULL)
+ p = strchr (format, '\0');
+ if (p != format)
+ gomp_display_string (buffer, size, &ret,
+ format, p - format);
+ if (*p == '\0')
+ break;
+ p++;
+ if (*p == '%')
+ {
+ gomp_display_string (buffer, size, &ret, "%", 1);
+ format = p + 1;
+ continue;
+ }
+ if (*p == '0')
+ {
+ zero = true;
+ p++;
+ if (*p != '.')
+ gomp_fatal ("leading zero not followed by dot in affinity format");
+ }
+ if (*p == '.')
+ {
+ right = true;
+ p++;
+ }
+ if (*p >= '1' && *p <= '9')
+ {
+ char *end;
+ sz = strtoul (p, &end, 10);
+ p = end;
+ }
+ else if (zero || right)
+ gomp_fatal ("leading zero or right justification in affinity format "
+ "requires size");
+ c = *p;
+ if (c == '{')
+ {
+ int i;
+ for (i = 0;
+ i < sizeof (affinity_types) / sizeof (affinity_types[0]); ++i)
+ if (strncmp (p + 1, affinity_types[i].long_str,
+ affinity_types[i].long_len) == 0
+ && p[affinity_types[i].long_len + 1] == '}')
+ {
+ c = affinity_types[i].short_c;
+ p += affinity_types[i].long_len + 1;
+ break;
+ }
+ if (c == '{')
+ {
+ char *q = strchr (p + 1, '}');
+ if (q)
+ gomp_fatal ("unsupported long type name '%.*s' in affinity "
+ "format", (int) (q - (p + 1)), p + 1);
+ else
+ gomp_fatal ("unterminated long type name '%s' in affinity "
+ "format", p + 1);
+ }
+ }
+ switch (c)
+ {
+ case 'L':
+ val = ts->level;
+ goto do_int;
+ case 'n':
+ val = ts->team_id;
+ goto do_int;
+ case 'h':
+ gomp_display_hostname (buffer, size, &ret, right, sz);
+ break;
+ case 'P':
+#ifdef HAVE_GETPID
+ val = getpid ();
+#else
+ val = 0;
+#endif
+ goto do_int;
+ case 'T':
+#if defined(LIBGOMP_USE_PTHREADS) && defined(__GNUC__)
+ /* Handle integral pthread_t. */
+ if (__builtin_classify_type (handle) == 1)
+ {
+ char buf[3 * (sizeof (handle) + sizeof (int)) + 4];
+
+ if (sizeof (handle) == sizeof (long))
+ sprintf (buf, "0x%lx", (long) handle);
+ else if (sizeof (handle) == sizeof (long long))
+ sprintf (buf, "0x%llx", (long long) handle);
+ else
+ sprintf (buf, "0x%x", (int) handle);
+ gomp_display_num (buffer, size, &ret, zero, right, sz, buf);
+ break;
+ }
+ /* And pointer pthread_t. */
+ else if (__builtin_classify_type (handle) == 5)
+ {
+ char buf[3 * (sizeof (uintptr_t) + sizeof (int)) + 4];
+
+ if (sizeof (uintptr_t) == sizeof (long))
+ sprintf (buf, "0x%lx", (long) (uintptr_t) handle);
+ else if (sizeof (uintptr_t) == sizeof (long long))
+ sprintf (buf, "0x%llx", (long long) (uintptr_t) handle);
+ else
+ sprintf (buf, "0x%x", (int) (uintptr_t) handle);
+ gomp_display_num (buffer, size, &ret, zero, right, sz, buf);
+ break;
+ }
+#endif
+ val = 0;
+ goto do_int;
+ case 'N':
+ val = ts->team ? ts->team->nthreads : 1;
+ goto do_int;
+ case 'A':
+ val = ts->team ? ts->team->prev_ts.team_id : -1;
+ goto do_int;
+ case 'a':
+ if (sz == (size_t) -1)
+ gomp_display_affinity_place (buffer, size, &ret,
+ place - 1);
+ else if (right)
+ {
+ size_t len = 0;
+ gomp_display_affinity_place (NULL, 0, &len, place - 1);
+ if (len < sz)
+ gomp_display_repeat (buffer, size, &ret, ' ', sz - len);
+ gomp_display_affinity_place (buffer, size, &ret, place - 1);
+ }
+ else
+ {
+ size_t start = ret;
+ gomp_display_affinity_place (buffer, size, &ret, place - 1);
+ if (ret - start < sz)
+ gomp_display_repeat (buffer, size, &ret, ' ', sz - (ret - start));
+ }
+ break;
+ do_int:
+ gomp_display_int (buffer, size, &ret, zero, right, sz, val);
+ break;
+ default:
+ gomp_fatal ("unsupported type %c in affinity format", c);
+ }
+ format = p + 1;
+ }
+ while (1);
+ return ret;
+}
+
+size_t
+omp_capture_affinity (char *buffer, size_t size, const char *format)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ size_t ret
+ = gomp_display_affinity (buffer, size,
+ format && *format
+ ? format : gomp_affinity_format_var,
+ gomp_thread_self (), &thr->ts, thr->place);
+ if (size)
+ {
+ if (ret >= size)
+ buffer[size - 1] = '\0';
+ else
+ buffer[ret] = '\0';
+ }
+ return ret;
+}
+ialias (omp_capture_affinity)
+
+void
+omp_display_affinity (const char *format)
+{
+ char buf[512];
+ char *b;
+ size_t ret = ialias_call (omp_capture_affinity) (buf, sizeof buf, format);
+ if (ret < sizeof buf)
+ {
+ buf[ret] = '\n';
+ fwrite (buf, 1, ret + 1, stderr);
+ return;
+ }
+ b = gomp_malloc (ret + 1);
+ ialias_call (omp_capture_affinity) (b, ret + 1, format);
+ b[ret] = '\n';
+ fwrite (b, 1, ret + 1, stderr);
+ free (b);
+}
+
+void
+gomp_display_affinity_thread (gomp_thread_handle handle,
+ struct gomp_team_state *ts, unsigned int place)
+{
+ char buf[512];
+ char *b;
+ size_t ret = gomp_display_affinity (buf, sizeof buf, gomp_affinity_format_var,
+ handle, ts, place);
+ if (ret < sizeof buf)
+ {
+ buf[ret] = '\n';
+ fwrite (buf, 1, ret + 1, stderr);
+ return;
+ }
+ b = gomp_malloc (ret + 1);
+ gomp_display_affinity (b, ret + 1, gomp_affinity_format_var,
+ handle, ts, place);
+ b[ret] = '\n';
+ fwrite (b, 1, ret + 1, stderr);
+ free (b);
+}
--- libgomp/affinity.c.jj 2018-04-30 13:21:02.853864869 +0200
+++ libgomp/affinity.c 2018-05-23 11:37:46.299744109 +0200
@@ -138,5 +138,18 @@ gomp_get_place_proc_ids_8 (int place_num
(void) ids;
}
+void
+gomp_display_affinity_place (char *buffer, size_t size, size_t *ret,
+ int place)
+{
+ cpu_set_t *cpusetp;
+ char buf[sizeof (long) * 3 + 4];
+ if (gomp_available_cpus > 1)
+ sprintf (buf, "0-%lu", gomp_available_cpus - 1);
+ else
+ strcpy (buf, "0");
+ gomp_display_string (buffer, size, ret, buf, strlen (buf));
+}
+
ialias(omp_get_place_num_procs)
ialias(omp_get_place_proc_ids)
--- libgomp/config/linux/affinity.c.jj 2018-04-30 13:20:51.454860277 +0200
+++ libgomp/config/linux/affinity.c 2018-05-23 11:24:14.809081402 +0200
@@ -396,6 +396,56 @@ gomp_get_place_proc_ids_8 (int place_num
*ids++ = i;
}
+void
+gomp_display_affinity_place (char *buffer, size_t size, size_t *ret,
+ int place)
+{
+ cpu_set_t *cpusetp;
+ char buf[sizeof (long) * 3 + 4];
+ if (place >= 0 && place < gomp_places_list_len)
+ cpusetp = (cpu_set_t *) gomp_places_list[place];
+ else if (gomp_cpusetp)
+ cpusetp = gomp_cpusetp;
+ else
+ {
+ if (gomp_available_cpus > 1)
+ sprintf (buf, "0-%lu", gomp_available_cpus - 1);
+ else
+ strcpy (buf, "0");
+ gomp_display_string (buffer, size, ret, buf, strlen (buf));
+ return;
+ }
+
+ unsigned long i, max = 8 * gomp_cpuset_size, start;
+ bool prev_set = false;
+ start = max;
+ for (i = 0; i <= max; i++)
+ {
+ bool this_set;
+ if (i == max)
+ this_set = false;
+ else
+ this_set = CPU_ISSET_S (i, gomp_cpuset_size, cpusetp);
+ if (this_set != prev_set)
+ {
+ prev_set = this_set;
+ if (this_set)
+ {
+ char *p = buf;
+ if (start != max)
+ *p++ = ',';
+ sprintf (p, "%lu", i);
+ start = i;
+ }
+ else if (i == start + 1)
+ continue;
+ else
+ sprintf (buf, "-%lu", i - 1);
+ gomp_display_string (buffer, size, ret, buf, strlen (buf));
+ }
+ }
+}
+
ialias(omp_get_place_num_procs)
ialias(omp_get_place_proc_ids)
--- libgomp/env.c.jj 2018-04-30 13:21:04.806865641 +0200
+++ libgomp/env.c 2018-05-23 12:38:58.023091979 +0200
@@ -88,6 +88,9 @@ void **gomp_places_list;
unsigned long gomp_places_list_len;
int gomp_debug_var;
unsigned int gomp_num_teams_var;
+bool gomp_display_affinity_var;
+char *gomp_affinity_format_var = "level %L thread %T affinity %a";
+size_t gomp_affinity_format_len;
char *goacc_device_type;
int goacc_device_num;
@@ -1197,6 +1200,10 @@ handle_omp_display_env (unsigned long st
gomp_global_icv.default_device_var);
fprintf (stderr, " OMP_MAX_TASK_PRIORITY = '%d'\n",
gomp_max_task_priority_var);
+ fprintf (stderr, " OMP_DISPLAY_AFFINITY = '%s'\n",
+ gomp_display_affinity_var ? "TRUE" : "FALSE");
+ fprintf (stderr, " OMP_AFFINITY_FORMAT = '%s'\n",
+ gomp_affinity_format_var);
if (verbose)
{
@@ -1228,6 +1235,7 @@ initialize_env (void)
parse_boolean ("OMP_DYNAMIC", &gomp_global_icv.dyn_var);
parse_boolean ("OMP_NESTED", &gomp_global_icv.nest_var);
parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var);
+ parse_boolean ("OMP_DISPLAY_AFFINITY", &gomp_display_affinity_var);
parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv.default_device_var, true);
parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var, true);
parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var,
@@ -1277,6 +1285,13 @@ initialize_env (void)
}
if (gomp_global_icv.bind_var != omp_proc_bind_false)
gomp_init_affinity ();
+
+ {
+ const char *env = getenv ("OMP_AFFINITY_FORMAT");
+ if (env != NULL)
+ gomp_set_affinity_format (env, strlen (env));
+ }
+
wait_policy = parse_wait_policy ();
if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var))
{
--- libgomp/fortran.c.jj 2018-04-30 13:21:03.011864928 +0200
+++ libgomp/fortran.c 2018-05-23 16:15:31.826411733 +0200
@@ -28,6 +28,8 @@
#include "libgomp.h"
#include "libgomp_f.h"
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
#include <limits.h>
#ifdef HAVE_ATTRIBUTE_ALIAS
@@ -576,3 +578,84 @@ omp_get_max_task_priority_ (void)
{
return omp_get_max_task_priority ();
}
+
+void
+omp_set_affinity_format_ (const char *format, size_t format_len)
+{
+ gomp_set_affinity_format (format, format_len);
+}
+
+int32_t
+omp_get_affinity_format_ (char *buffer, size_t buffer_len)
+{
+ size_t len = strlen (gomp_affinity_format_var);
+ if (buffer_len)
+ {
+ if (len < buffer_len)
+ {
+ memcpy (buffer, gomp_affinity_format_var, len);
+ memset (buffer + len, ' ', buffer_len - len);
+ }
+ else
+ memcpy (buffer, gomp_affinity_format_var, buffer_len);
+ }
+ return len;
+}
+
+void
+omp_display_affinity_ (const char *format, size_t format_len)
+{
+ char *fmt = NULL, fmt_buf[256];
+ char buf[512];
+ if (format_len)
+ {
+ fmt = format_len < 256 ? fmt_buf : gomp_malloc (format_len + 1);
+ memcpy (fmt, format, format_len);
+ fmt[format_len] = '\0';
+ }
+ struct gomp_thread *thr = gomp_thread ();
+ size_t ret
+ = gomp_display_affinity (buf, sizeof buf,
+ format_len ? fmt : gomp_affinity_format_var,
+ gomp_thread_self (), &thr->ts, thr->place);
+ if (ret < sizeof buf)
+ {
+ buf[ret] = '\n';
+ fwrite (buf, 1, ret + 1, stderr);
+ }
+ else
+ {
+ char *b = gomp_malloc (ret + 1);
+ gomp_display_affinity (buf, sizeof buf,
+ format_len ? fmt : gomp_affinity_format_var,
+ gomp_thread_self (), &thr->ts, thr->place);
+ b[ret] = '\n';
+ fwrite (b, 1, ret + 1, stderr);
+ free (b);
+ }
+ if (fmt && fmt != fmt_buf)
+ free (fmt);
+}
+
+int32_t
+omp_capture_affinity_ (char *buffer, const char *format,
+ size_t buffer_len, size_t format_len)
+{
+ char *fmt = NULL, fmt_buf[256];
+ if (format_len)
+ {
+ fmt = format_len < 256 ? fmt_buf : gomp_malloc (format_len + 1);
+ memcpy (fmt, format, format_len);
+ fmt[format_len] = '\0';
+ }
+ struct gomp_thread *thr = gomp_thread ();
+ size_t ret
+ = gomp_display_affinity (buffer, buffer_len,
+ format_len ? fmt : gomp_affinity_format_var,
+ gomp_thread_self (), &thr->ts, thr->place);
+ if (fmt && fmt != fmt_buf)
+ free (fmt);
+ if (ret < buffer_len)
+ memset (buffer + ret, ' ', buffer_len - ret);
+ return ret;
+}
--- libgomp/omp.h.in.jj 2018-05-04 12:31:28.863633774 +0200
+++ libgomp/omp.h.in 2018-05-21 15:54:08.496902995 +0200
@@ -166,6 +166,13 @@ extern int omp_target_associate_ptr (con
__SIZE_TYPE__, int) __GOMP_NOTHROW;
extern int omp_target_disassociate_ptr (const void *, int) __GOMP_NOTHROW;
+extern void omp_set_affinity_format (const char *) __GOMP_NOTHROW;
+extern __SIZE_TYPE__ omp_get_affinity_format (char *, __SIZE_TYPE__)
+ __GOMP_NOTHROW;
+extern void omp_display_affinity (const char *) __GOMP_NOTHROW;
+extern __SIZE_TYPE__ omp_capture_affinity (char *, __SIZE_TYPE__, const char *)
+ __GOMP_NOTHROW;
+
#ifdef __cplusplus
}
#endif
--- libgomp/omp_lib.f90.in.jj 2018-04-30 13:19:49.305835311 +0200
+++ libgomp/omp_lib.f90.in 2018-05-23 13:14:15.873893636 +0200
@@ -433,4 +433,31 @@
end function omp_get_max_task_priority
end interface
+ interface
+ subroutine omp_set_affinity_format (format)
+ character(len=*), intent(in) :: format
+ end subroutine omp_set_affinity_format
+ end interface
+
+ interface
+ function omp_get_affinity_format (buffer)
+ integer (4) :: omp_get_affinity_format
+ character(len=*), intent(out) :: buffer
+ end function omp_get_affinity_format
+ end interface
+
+ interface
+ subroutine omp_display_affinity (format)
+ character(len=*), intent(in) :: format
+ end subroutine omp_display_affinity
+ end interface
+
+ interface
+ function omp_capture_affinity (buffer, format)
+ integer (4) :: omp_capture_affinity
+ character(len=*), intent(out) :: buffer
+ character(len=*), intent(in) :: format
+ end function omp_capture_affinity
+ end interface
+
end module omp_lib
--- libgomp/omp_lib.h.in.jj 2018-04-30 13:21:07.207866607 +0200
+++ libgomp/omp_lib.h.in 2018-05-23 13:21:07.605241351 +0200
@@ -126,3 +126,8 @@
external omp_get_max_task_priority
integer(4) omp_get_max_task_priority
+
+ external omp_set_affinity_format, omp_get_affinity_format
+ external omp_display_affinity, omp_capture_affinity
+ integer(4) omp_get_affinity_format
+ integer(4) omp_capture_affinity
--- libgomp/team.c.jj 2018-04-30 13:19:48.674835063 +0200
+++ libgomp/team.c 2018-05-23 16:45:09.478108168 +0200
@@ -58,6 +58,7 @@ struct gomp_thread_start_data
struct gomp_thread_pool *thread_pool;
unsigned int place;
bool nested;
+ pthread_t handle;
};
@@ -89,6 +90,9 @@ gomp_thread_start (void *xdata)
thr->ts = data->ts;
thr->task = data->task;
thr->place = data->place;
+#ifdef GOMP_NEEDS_THREAD_HANDLE
+ thr->handle = data->handle;
+#endif
thr->ts.team->ordered_release[thr->ts.team_id] = &thr->release;
@@ -312,6 +316,7 @@ gomp_team_start (void (*fn) (void *), vo
unsigned int s = 0, rest = 0, p = 0, k = 0;
unsigned int affinity_count = 0;
struct gomp_thread **affinity_thr = NULL;
+ bool force_display = false;
thr = gomp_thread ();
nested = thr->ts.level;
@@ -319,7 +324,12 @@ gomp_team_start (void (*fn) (void *), vo
task = thr->task;
icv = task ? &task->icv : &gomp_global_icv;
if (__builtin_expect (gomp_places_list != NULL, 0) && thr->place == 0)
- gomp_init_affinity ();
+ {
+ gomp_init_affinity ();
+ if (__builtin_expect (gomp_display_affinity_var, 0) && nthreads == 1)
+ gomp_display_affinity_thread (gomp_thread_self (), &thr->ts,
+ thr->place);
+ }
/* Always save the previous state, even if this isn't a nested team.
In particular, we should save any work share state from an outer
@@ -338,6 +348,9 @@ gomp_team_start (void (*fn) (void *), vo
#endif
thr->ts.static_trip = 0;
thr->task = &team->implicit_task[0];
+#ifdef GOMP_NEEDS_THREAD_HANDLE
+ thr->handle = pthread_self ();
+#endif
nthreads_var = icv->nthreads_var;
if (__builtin_expect (gomp_nthreads_var_list != NULL, 0)
&& thr->ts.level < gomp_nthreads_var_list_len)
@@ -465,7 +478,7 @@ gomp_team_start (void (*fn) (void *), vo
pool->threads
= gomp_realloc (pool->threads,
pool->threads_size
- * sizeof (struct gomp_thread_data *));
+ * sizeof (struct gomp_thread *));
}
/* Release existing idle threads. */
@@ -540,6 +553,7 @@ gomp_team_start (void (*fn) (void *), vo
+ place_partition_len))
{
unsigned int l;
+ force_display = true;
if (affinity_thr == NULL)
{
unsigned int j;
@@ -719,12 +733,11 @@ gomp_team_start (void (*fn) (void *), vo
}
start_data = gomp_alloca (sizeof (struct gomp_thread_start_data)
- * (nthreads-i));
+ * (nthreads - i));
/* Launch new threads. */
for (; i < nthreads; ++i)
{
- pthread_t pt;
int err;
start_data->ts.place_partition_off = thr->ts.place_partition_off;
@@ -814,7 +827,9 @@ gomp_team_start (void (*fn) (void *), vo
start_data->nested = nested;
attr = gomp_adjust_thread_attr (attr, &thread_attr);
- err = pthread_create (&pt, attr, gomp_thread_start, start_data++);
+ err = pthread_create (&start_data->handle, attr, gomp_thread_start,
+ start_data);
+ start_data++;
if (err != 0)
gomp_fatal ("Thread creation failed: %s", strerror (err));
}
@@ -854,6 +869,42 @@ gomp_team_start (void (*fn) (void *), vo
gomp_mutex_unlock (&gomp_managed_threads_lock);
#endif
}
+ if (__builtin_expect (gomp_display_affinity_var, 0))
+ {
+ if (nested
+ || nthreads != old_threads_used
+ || force_display)
+ {
+ gomp_display_affinity_thread (gomp_thread_self (), &thr->ts,
+ thr->place);
+ if (nested)
+ {
+ start_data -= nthreads - 1;
+ for (i = 1; i < nthreads; ++i)
+ {
+ gomp_display_affinity_thread (
+#ifdef LIBGOMP_USE_PTHREADS
+ start_data->handle,
+#else
+ gomp_thread_self (),
+#endif
+ &start_data->ts,
+ start_data->place);
+ start_data++;
+ }
+ }
+ else
+ {
+ for (i = 1; i < nthreads; ++i)
+ {
+ gomp_thread_handle handle
+ = gomp_thread_to_pthread_t (pool->threads[i]);
+ gomp_display_affinity_thread (handle, &pool->threads[i]->ts,
+ pool->threads[i]->place);
+ }
+ }
+ }
+ }
if (__builtin_expect (affinity_thr != NULL, 0)
&& team->prev_ts.place_partition_len > 64)
free (affinity_thr);
--- libgomp/configure.jj 2018-04-30 13:21:02.531864728 +0200
+++ libgomp/configure 2018-05-22 14:16:34.830984930 +0200
@@ -15784,6 +15784,72 @@ fi
fi
+# Check for uname.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+ #include <stdlib.h>
+ #include <sys/utsname.h>
+int
+main ()
+{
+struct utsname buf;
+ volatile size_t len = 0;
+ if (!uname (buf))
+ len = strlen (buf.nodename);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_UNAME 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# Check for gethostname.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <unistd.h>
+int
+main ()
+{
+
+ char buf[256];
+ if (gethostname (buf, sizeof (buf) - 1) == 0)
+ buf[255] = '\0';
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_GETHOSTNAME 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# Check for getpid.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <unistd.h>
+int
+main ()
+{
+int pid = getpid ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_GETPID 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
# See if we support thread-local storage.
--- libgomp/config.h.in.jj 2017-05-04 15:04:53.606372292 +0200
+++ libgomp/config.h.in 2018-05-22 14:16:32.000000000 +0200
@@ -33,9 +33,15 @@
/* Define to 1 if you have the `getgid' function. */
#undef HAVE_GETGID
+/* Define if gethostname is supported. */
+#undef HAVE_GETHOSTNAME
+
/* Define to 1 if you have the `getloadavg' function. */
#undef HAVE_GETLOADAVG
+/* Define if getpid is supported. */
+#undef HAVE_GETPID
+
/* Define to 1 if you have the `getuid' function. */
#undef HAVE_GETUID
@@ -103,6 +109,9 @@
/* Define to 1 if the target supports thread-local storage. */
#undef HAVE_TLS
+/* Define if uname is supported and struct utsname has nodename field. */
+#undef HAVE_UNAME
+
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
--- libgomp/Makefile.in.jj 2018-04-30 13:19:46.934834362 +0200
+++ libgomp/Makefile.in 2018-05-21 17:21:39.227956241 +0200
@@ -180,7 +180,8 @@ am_libgomp_la_OBJECTS = alloc.lo atomic.
sem.lo bar.lo ptrlock.lo time.lo fortran.lo affinity.lo \
target.lo splay-tree.lo libgomp-plugin.lo oacc-parallel.lo \
oacc-host.lo oacc-init.lo oacc-mem.lo oacc-async.lo \
- oacc-plugin.lo oacc-cuda.lo priority_queue.lo $(am__objects_1)
+ oacc-plugin.lo oacc-cuda.lo priority_queue.lo affinity-fmt.lo \
+ $(am__objects_1)
libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/../depcomp
@@ -436,7 +437,7 @@ libgomp_la_SOURCES = alloc.c atomic.c ba
affinity.c target.c splay-tree.c libgomp-plugin.c \
oacc-parallel.c oacc-host.c oacc-init.c oacc-mem.c \
oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c \
- $(am__append_3)
+ affinity-fmt.c $(am__append_3)
# Nvidia PTX OpenACC plugin.
@PLUGIN_NVPTX_TRUE@libgomp_plugin_nvptx_version_info = -version-info $(libtool_VERSION)
@@ -600,6 +601,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/affinity.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/affinity-fmt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomic.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bar.Plo@am__quote@
--- libgomp/testsuite/libgomp.c-c++-common/display-affinity-1.c.jj 2018-05-23 10:06:58.261621753 +0200
+++ libgomp/testsuite/libgomp.c-c++-common/display-affinity-1.c 2018-05-23 11:21:57.641972727 +0200
@@ -0,0 +1,91 @@
+/* { dg-set-target-env-var OMP_PROC_BIND "spread,close" } */
+/* { dg-set-target-env-var OMP_PLACES "cores" } */
+/* { dg-set-target-env-var OMP_NUM_THREADS "4" } */
+/* { dg-set-target-env-var OMP_AFFINITY_FORMAT "hello" } */
+
+#include <omp.h>
+#include <string.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+#define FMT "L:%0.5L%%%n>%32h<!%.33{host}!%.6P_%T_%0.18T_%0.7{ancestor_tnum} %18a"
+ char buf[] = FMT, hostname[256], buf2[512 + 32], *q;
+ size_t l, l2, l3;
+ char *r = getenv ("OMP_AFFINITY_FORMAT");
+ if (r && strcmp (r, "hello") == 0)
+ {
+ if (omp_get_affinity_format (NULL, 0) != 5)
+ abort ();
+ if (omp_get_affinity_format (buf2, 3) != 5
+ || strcmp (buf2, "he") != 0)
+ abort ();
+ if (omp_get_affinity_format (buf2, 6) != 5
+ || strcmp (buf2, "hello") != 0)
+ abort ();
+ }
+ omp_set_affinity_format (buf);
+ memset (buf, '^', sizeof (buf));
+ if (omp_get_affinity_format (NULL, 0) != sizeof (buf) - 1)
+ abort ();
+ if (omp_get_affinity_format (buf, 3) != sizeof (buf) - 1
+ || buf[0] != FMT[0] || buf[1] != FMT[1] || buf[2] != '\0')
+ abort ();
+ memset (buf, ' ', sizeof (buf));
+ if (omp_get_affinity_format (buf, sizeof (buf) - 1) != sizeof (buf) - 1
+ || strncmp (buf, FMT, sizeof (buf) - 2) != 0
+ || buf[sizeof (buf) - 2] != '\0')
+ abort ();
+ memset (buf, '-', sizeof (buf));
+ if (omp_get_affinity_format (buf, sizeof (buf)) != sizeof (buf) - 1
+ || strcmp (buf, FMT) != 0)
+ abort ();
+ memset (buf, '0', sizeof (buf));
+ omp_display_affinity (NULL);
+ omp_display_affinity ("");
+ omp_display_affinity ("%%%0.9N");
+ omp_set_affinity_format ("%{host}");
+ l = omp_capture_affinity (hostname, sizeof hostname, NULL);
+ if (l < sizeof (hostname))
+ {
+ if (strlen (hostname) != l)
+ abort ();
+ l2 = omp_capture_affinity (NULL, 0,
+ "%0.5{thread_level}%%%32{host}|||%.33h"
+ "%0.7A%3N!%N!");
+ if (l2 != (5 + 1 + (l > 32 ? l : 32) + 3 + (l > 33 ? l : 33)
+ + 7 + 3 + 1 + 1 + 1))
+ abort ();
+ omp_set_affinity_format ("%.5L%%%32h|||%.33{host}%0.7{ancestor_tnum}"
+ "%3{num_threads}!%{num_threads}!");
+ l3 = omp_capture_affinity (buf2, sizeof buf2, "");
+ if (l3 != l2)
+ abort ();
+ if (memcmp (buf2, " 0%", 5 + 1) != 0)
+ abort ();
+ q = buf2 + 6;
+ if (memcmp (q, hostname, l) != 0)
+ abort ();
+ q += l;
+ if (l < 32)
+ for (l3 = 32 - l; l3; l3--)
+ if (*q++ != ' ')
+ abort ();
+ if (memcmp (q, "|||", 3) != 0)
+ abort ();
+ q += 3;
+ if (l < 33)
+ for (l3 = 33 - l; l3; l3--)
+ if (*q++ != ' ')
+ abort ();
+ if (memcmp (q, hostname, l) != 0)
+ abort ();
+ q += l;
+ if (strcmp (q, "-0000011 !1!") != 0)
+ abort ();
+ }
+ #pragma omp parallel num_threads (4) proc_bind(spread)
+ omp_display_affinity ("%0.2A!%n!%.4L!%N;%a");
+ return 0;
+}
--- libgomp/testsuite/libgomp.fortran/display-affinity-1.f90.jj 2018-05-23 13:45:12.788535876 +0200
+++ libgomp/testsuite/libgomp.fortran/display-affinity-1.f90 2018-05-23 14:24:01.349865094 +0200
@@ -0,0 +1,33 @@
+! { dg-set-target-env-var OMP_PROC_BIND "spread,close" }
+! { dg-set-target-env-var OMP_PLACES "cores" }
+! { dg-set-target-env-var OMP_NUM_THREADS "4" }
+! { dg-set-target-env-var OMP_AFFINITY_FORMAT "hello" }
+
+ use omp_lib
+ character(len=68) :: buf, buf2
+ character(len=8) :: buf3
+ character(len=1) :: buf4
+ integer :: l1, l2
+
+ buf = 'L:%0.5L%%%n>%32h<!%.33{host}!%.6P_%T_%0.18T_%0.7{ancestor_tnum} %18a'
+ call omp_set_affinity_format (format = buf)
+ if (omp_get_affinity_format (buf4) /= 68) stop 1
+ if (buf4 /= 'L') stop 2
+ if (omp_get_affinity_format (buf2) /= 68) stop 3
+ if (buf2 /= buf) stop 4
+ if (omp_get_affinity_format (buf3) /= 68) stop 5
+ if (buf3 /= 'L:%0.5L%') stop 6
+ call omp_display_affinity ('')
+ call omp_display_affinity ('%%%0.9N')
+ l1 = omp_capture_affinity (buf4, '%0.5{thread_level}%%|||%0.7A%3N!%N!')
+ buf = '%.5L%%|||%0.7{ancestor_tnum}%3{num_threads}!%{num_threads}!'
+ call omp_set_affinity_format (trim (buf))
+ l2 = omp_capture_affinity (buf2, '')
+ if (l1 /= l2) stop 7
+ if (l1 /= 22) stop 8
+ if (buf2 /= ' 0%|||-0000011 !1!') stop 9
+ if (buf4 /= '0') stop 10
+!$omp parallel num_threads (4) proc_bind(spread)
+ call omp_display_affinity ('%0.2A!%n!%.4L!%N;%a')
+!$omp end parallel
+end
Jakub
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2018-05-23 14:57 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-23 14:59 [gomp5] Implement omp_[sg]et_affinity_format, omp_{capture,display}_affinity, OMP_DISPLAY_AFFINITY and OMP_AFFINITY_FORMAT Jakub Jelinek
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).