diff mbox series

[committed] libgomp: Use TLS storage for omp_get_num_teams()/omp_get_team_num() values

Message ID 20211111131921.GP2710@tucnak
State New
Headers show
Series [committed] libgomp: Use TLS storage for omp_get_num_teams()/omp_get_team_num() values | expand

Commit Message

Jakub Jelinek Nov. 11, 2021, 1:19 p.m. UTC
Hi!

When thinking about GOMP_teams3, I've realized that using global variables
for the values returned by omp_get_num_teams()/omp_get_team_num() calls
is incorrect even with our right now dumb way of implementing host teams.
The problems are two, one is if host teams is used from multiple pthread_create
created threads - the spec says that host teams can't be nested inside of
explicit parallel or other teams constructs, but with pthread_create the
standard says obviously nothing about it.  Another more important thing
is host fallback, right now we don't do anything for omp_get_num_teams()
or omp_get_team_num() which was fine before host teams was introduced and
the 5.1 requirement that num_teams clause specifies minimum of teams, but
with the global vars it means inside of target teams num_teams (2) we happily
return omp_get_num_teams() == 4 if the target teams is inside of host teams
with num_teams(4).  With target fallback being invoked from parallel
regions global vars simply can't work right on the host.  Both with nowait
target and with synchronous target too, as while doing host fallback from
one thread a different thread could see wrong values.

So, this patch moves them to struct gomp_thread and propagates those for
parallel to child threads.  For host fallback, the implicit zeroing of
*thr results in us returning omp_get_num_teams () == 1 and
omp_get_team_num () == 0 which is fine for target teams without num_teams
clause, for target teams with num_teams clause something to work on and
for target without teams nested in it I've asked on omp-lang what should
be done.

Regtested on x86_64-linux, committed to trunk.

2021-11-11  Jakub Jelinek  <jakub@redhat.com>

	* libgomp.h (struct gomp_thread): Add num_teams and team_num members.
	* team.c (struct gomp_thread_start_data): Likewise.
	(gomp_thread_start): Initialize thr->num_teams and thr->team_num.
	(gomp_team_start): Initialize start_data->num_teams and
	start_data->team_num.  Update nthr->num_teams and nthr->team_num.
	* teams.c (gomp_num_teams, gomp_team_num): Remove.
	(GOMP_teams_reg): Set and restore thr->num_teams and thr->team_num
	instead of gomp_num_teams and gomp_team_num.
	(omp_get_num_teams): Use thr->num_teams + 1 instead of gomp_num_teams.
	(omp_get_team_num): Use thr->team_num instead of gomp_team_num.
	* testsuite/libgomp.c/teams-4.c: New test.



	Jakub
diff mbox series

Patch

--- libgomp/libgomp.h.jj	2021-10-20 09:34:47.004331626 +0200
+++ libgomp/libgomp.h	2021-11-11 12:44:47.710092897 +0100
@@ -768,6 +768,14 @@  struct gomp_thread
   /* User pthread thread pool */
   struct gomp_thread_pool *thread_pool;
 
+#ifdef LIBGOMP_USE_PTHREADS
+  /* omp_get_num_teams () - 1.  */
+  unsigned int num_teams;
+
+  /* omp_get_team_num ().  */
+  unsigned int team_num;
+#endif
+
 #if defined(LIBGOMP_USE_PTHREADS) \
     && (!defined(HAVE_TLS) \
 	|| !defined(__GLIBC__) \
--- libgomp/team.c.jj	2021-09-28 11:34:29.380146749 +0200
+++ libgomp/team.c	2021-11-11 12:55:22.524952564 +0100
@@ -56,6 +56,8 @@  struct gomp_thread_start_data
   struct gomp_task *task;
   struct gomp_thread_pool *thread_pool;
   unsigned int place;
+  unsigned int num_teams;
+  unsigned int team_num;
   bool nested;
   pthread_t handle;
 };
@@ -88,6 +90,8 @@  gomp_thread_start (void *xdata)
   thr->ts = data->ts;
   thr->task = data->task;
   thr->place = data->place;
+  thr->num_teams = data->num_teams;
+  thr->team_num = data->team_num;
 #ifdef GOMP_NEEDS_THREAD_HANDLE
   thr->handle = data->handle;
 #endif
@@ -645,6 +649,8 @@  gomp_team_start (void (*fn) (void *), vo
 	  nthr->ts.single_count = 0;
 #endif
 	  nthr->ts.static_trip = 0;
+	  nthr->num_teams = thr->num_teams;
+	  nthr->team_num = thr->team_num;
 	  nthr->task = &team->implicit_task[i];
 	  nthr->place = place;
 	  gomp_init_task (nthr->task, task, icv);
@@ -833,6 +839,8 @@  gomp_team_start (void (*fn) (void *), vo
       start_data->ts.single_count = 0;
 #endif
       start_data->ts.static_trip = 0;
+      start_data->num_teams = thr->num_teams;
+      start_data->team_num = thr->team_num;
       start_data->task = &team->implicit_task[i];
       gomp_init_task (start_data->task, task, icv);
       team->implicit_task[i].icv.nthreads_var = nthreads_var;
--- libgomp/teams.c.jj	2021-10-11 12:20:21.927063104 +0200
+++ libgomp/teams.c	2021-11-11 12:43:58.769797557 +0100
@@ -28,14 +28,12 @@ 
 #include "libgomp.h"
 #include <limits.h>
 
-static unsigned gomp_num_teams = 1, gomp_team_num = 0;
-
 void
 GOMP_teams_reg (void (*fn) (void *), void *data, unsigned int num_teams,
 		unsigned int thread_limit, unsigned int flags)
 {
+  struct gomp_thread *thr = gomp_thread ();
   (void) flags;
-  (void) num_teams;
   unsigned old_thread_limit_var = 0;
   if (thread_limit == 0)
     thread_limit = gomp_teams_thread_limit_var;
@@ -48,11 +46,11 @@  GOMP_teams_reg (void (*fn) (void *), voi
     }
   if (num_teams == 0)
     num_teams = gomp_nteams_var ? gomp_nteams_var : 3;
-  gomp_num_teams = num_teams;
-  for (gomp_team_num = 0; gomp_team_num < num_teams; gomp_team_num++)
+  thr->num_teams = num_teams - 1;
+  for (thr->team_num = 0; thr->team_num < num_teams; thr->team_num++)
     fn (data);
-  gomp_num_teams = 1;
-  gomp_team_num = 0;
+  thr->num_teams = 0;
+  thr->team_num = 0;
   if (thread_limit)
     {
       struct gomp_task_icv *icv = gomp_icv (true);
@@ -63,13 +61,15 @@  GOMP_teams_reg (void (*fn) (void *), voi
 int
 omp_get_num_teams (void)
 {
-  return gomp_num_teams;
+  struct gomp_thread *thr = gomp_thread ();
+  return thr->num_teams + 1;
 }
 
 int
 omp_get_team_num (void)
 {
-  return gomp_team_num;
+  struct gomp_thread *thr = gomp_thread ();
+  return thr->team_num;
 }
 
 ialias (omp_get_num_teams)
--- libgomp/testsuite/libgomp.c/teams-4.c.jj	2021-11-11 13:13:05.834638687 +0100
+++ libgomp/testsuite/libgomp.c/teams-4.c	2021-11-11 13:27:37.730085919 +0100
@@ -0,0 +1,30 @@ 
+#include <omp.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+  if (omp_get_num_teams () != 1 || omp_get_team_num () != 0)
+    abort ();
+  #pragma omp parallel num_threads (2)
+  if (omp_get_num_teams () != 1 || omp_get_team_num () != 0)
+    abort ();
+  #pragma omp teams num_teams (4)
+  {
+    int team = omp_get_team_num ();
+    if (omp_get_num_teams () != 4 || (unsigned) team >= 4U)
+      abort ();
+    #pragma omp parallel num_threads (3)
+    if (omp_get_num_teams () != 4 || omp_get_team_num () != team)
+      abort ();
+    #pragma omp parallel if (0)
+    #pragma omp target
+    #pragma omp teams num_teams (2)
+    if (omp_get_num_teams () > 2
+	|| (unsigned) omp_get_team_num () >= 2U)
+      abort ();
+    if (omp_get_num_teams () != 4 || (unsigned) team >= 4U)
+      abort ();
+  }
+  return 0;
+}