This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gomp3] Implement new OpenMP 3.0 omp_* entrypoints in libgomp


Hi!

Tested on x86_64-linux, committed to gomp-3_0-branch.

2007-10-23  Jakub Jelinek  <jakub@redhat.com>

	* libgomp.h (gomp_schedule_type): Reorder enum to match
	omp_sched_t.
	(struct gomp_team_state): Add level field.
	* team.c (gomp_thread_start): Clear ts.level.
	(gomp_team_start): Initialize ts.level.
	* parallel.c (omp_in_parallel): Update comment.
	(omp_get_level, omp_get_ancestor_thread_num,
	omp_get_team_size, omp_get_active_level): New functions,
	add ialias.
	* env.c (omp_set_schedule, omp_get_schedule, omp_get_thread_limit,
	omp_set_max_active_levels, omp_get_max_active_levels): New functions,
	add ialias.
	* omp_lib.f90.in (omp_get_ancestor_thread_num): Handle
	integer (8) argument.
	* fortran.c (omp_set_schedule, omp_get_schedule,
	omp_get_thread_limit, omp_set_max_active_levels,
	omp_get_max_active_levels, omp_get_level,
	omp_get_ancestor_thread_num, omp_get_team_size,
	omp_get_active_level): New ialias_redirect.
	(omp_set_schedule_, omp_set_schedule_8_,
	omp_get_schedule_, omp_get_schedule_8_, omp_get_thread_limit_,
	omp_set_max_active_levels_, omp_set_max_active_levels_8_,
	omp_get_max_active_levels_, omp_get_level_,
	omp_get_ancestor_thread_num_, omp_get_ancestor_thread_num_8_,
	omp_get_team_size_, omp_get_team_size_8_, omp_get_active_level_):
	New functions.
	* libgomp.map (omp_set_schedule, omp_get_schedule,
	omp_get_thread_limit, omp_set_max_active_levels,
	omp_get_max_active_levels, omp_get_level,
	omp_get_ancestor_thread_num, omp_get_team_size, omp_get_active_level,
	omp_set_schedule_, omp_set_schedule_8_,
	omp_get_schedule_, omp_get_schedule_8_, omp_get_thread_limit_,
	omp_set_max_active_levels_, omp_set_max_active_levels_8_,
	omp_get_max_active_levels_, omp_get_level_,
	omp_get_ancestor_thread_num_, omp_get_ancestor_thread_num_8_,
	omp_get_team_size_, omp_get_team_size_8_, omp_get_active_level_):
	New exports @@OMP_3.0.
	* testsuite/libgomp.fortran/nested1.f90: New test.
	* testsuite/libgomp.fortran/lib4.f90: New test.
	* testsuite/libgomp.c/lib-2.c: New test.
	* testsuite/libgomp.c/nested-3.c: New test.

--- libgomp/parallel.c.jj	2007-10-22 22:11:45.000000000 +0200
+++ libgomp/parallel.c	2007-10-23 20:41:32.000000000 +0200
@@ -102,11 +102,12 @@ omp_get_thread_num (void)
   return gomp_thread ()->ts.team_id;
 }
 
-/* ??? This isn't right.  The definition of this function is false if any
-   of the IF clauses for any of the parallels is false.  Which is not the
-   same thing as any outer team having more than one thread.  */
+/* This wasn't right for OpenMP 2.5.  Active region used to be
+   one where IF clause doesn't evaluate to false, starting with
+   3.0 it is one with more than one thread in the team.  */
 
-int omp_in_parallel (void)
+int
+omp_in_parallel (void)
 {
   struct gomp_team *team = gomp_thread ()->ts.team;
 
@@ -120,7 +121,58 @@ int omp_in_parallel (void)
   return false;
 }
 
+int
+omp_get_level (void)
+{
+  return gomp_thread ()->ts.level;
+}
+
+int
+omp_get_ancestor_thread_num (int level)
+{
+  struct gomp_team_state *ts = &gomp_thread ()->ts;
+  if (level < 0 || level > ts->level)
+    return -1;
+  for (level = ts->level - level; level > 0; --level)
+    ts = &ts->team->prev_ts;
+  return ts->team_id;
+}
+
+int
+omp_get_team_size (int level)
+{
+  struct gomp_team_state *ts = &gomp_thread ()->ts;
+  if (level < 0 || level > ts->level)
+    return -1;
+  for (level = ts->level - level; level > 0; --level)
+    ts = &ts->team->prev_ts;
+  if (ts->team == NULL)
+    return 1;
+  else
+    return ts->team->nthreads;
+}
+
+int
+omp_get_active_level (void)
+{
+  struct gomp_team *team = gomp_thread ()->ts.team;
+  int active = 0;
+
+  while (team)
+    {
+      if (team->nthreads > 1)
+	++active;
+      team = team->prev_ts.team;
+    }
+
+  return active;
+}
+
 ialias (omp_get_num_threads)
 ialias (omp_get_max_threads)
 ialias (omp_get_thread_num)
 ialias (omp_in_parallel)
+ialias (omp_get_level)
+ialias (omp_get_ancestor_thread_num)
+ialias (omp_get_team_size)
+ialias (omp_get_active_level)
--- libgomp/team.c.jj	2007-10-22 22:11:45.000000000 +0200
+++ libgomp/team.c	2007-10-23 17:42:30.000000000 +0200
@@ -115,6 +115,7 @@ gomp_thread_start (void *xdata)
 	  thr->ts.team = NULL;
 	  thr->ts.work_share = NULL;
 	  thr->ts.team_id = 0;
+	  thr->ts.level = 0;
 	  thr->ts.work_share_generation = 0;
 	  thr->ts.static_trip = 0;
 
@@ -198,6 +199,7 @@ gomp_team_start (void (*fn) (void *), vo
   thr->ts.team = team;
   thr->ts.work_share = work_share;
   thr->ts.team_id = 0;
+  ++thr->ts.level;
   thr->ts.work_share_generation = 0;
   thr->ts.static_trip = 0;
 
@@ -243,6 +245,7 @@ gomp_team_start (void (*fn) (void *), vo
 	  nthr->ts.team = team;
 	  nthr->ts.work_share = work_share;
 	  nthr->ts.team_id = i;
+	  nthr->ts.level = team->prev_ts.level + 1;
 	  nthr->ts.work_share_generation = 0;
 	  nthr->ts.static_trip = 0;
 	  nthr->fn = fn;
@@ -289,6 +292,7 @@ gomp_team_start (void (*fn) (void *), vo
       start_data->ts.team = team;
       start_data->ts.work_share = work_share;
       start_data->ts.team_id = i;
+      start_data->ts.level = team->prev_ts.level + 1;
       start_data->ts.work_share_generation = 0;
       start_data->ts.static_trip = 0;
       start_data->fn = fn;
--- libgomp/libgomp.h.jj	2007-10-22 22:39:59.000000000 +0200
+++ libgomp/libgomp.h	2007-10-23 17:31:24.000000000 +0200
@@ -57,10 +57,10 @@
 
 enum gomp_schedule_type
 {
+  GFS_RUNTIME,
   GFS_STATIC,
   GFS_DYNAMIC,
   GFS_GUIDED,
-  GFS_RUNTIME,
   GFS_AUTO
 };
 
@@ -143,6 +143,9 @@ struct gomp_team_state
      threads in the team.  */
   unsigned team_id;
 
+  /* Nesting level.  */
+  unsigned level;
+
   /* The work share "generation" is a number that increases by one for
      each work share construct encountered in the dynamic flow of the
      program.  It is used to find the control data for the work share
--- libgomp/omp_lib.f90.in.jj	2007-10-23 15:24:22.000000000 +0200
+++ libgomp/omp_lib.f90.in	2007-10-23 18:07:13.000000000 +0200
@@ -259,11 +259,17 @@
           end function omp_get_level
         end interface
 
-        interface
-          function omp_get_ancestor_thread_num ()
+        interface omp_get_ancestor_thread_num
+          function omp_get_ancestor_thread_num (level)
             use omp_lib_kinds
+	    integer (4), intent (in) :: level
             integer (omp_integer_kind) :: omp_get_ancestor_thread_num
           end function omp_get_ancestor_thread_num
+          function omp_get_ancestor_thread_num_8 (level)
+            use omp_lib_kinds
+	    integer (8), intent (in) :: level
+            integer (omp_integer_kind) :: omp_get_ancestor_thread_num
+          end function omp_get_ancestor_thread_num_8
         end interface
 
         interface omp_get_team_size
--- libgomp/fortran.c.jj	2007-10-22 22:11:45.000000000 +0200
+++ libgomp/fortran.c	2007-10-23 19:25:42.000000000 +0200
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
    Contributed by Jakub Jelinek <jakub@redhat.com>.
 
    This file is part of the GNU OpenMP Library (libgomp).
@@ -60,6 +60,15 @@ ialias_redirect (omp_get_num_threads)
 ialias_redirect (omp_get_thread_num)
 ialias_redirect (omp_get_wtick)
 ialias_redirect (omp_get_wtime)
+ialias_redirect (omp_set_schedule)
+ialias_redirect (omp_get_schedule)
+ialias_redirect (omp_get_thread_limit)
+ialias_redirect (omp_set_max_active_levels)
+ialias_redirect (omp_get_max_active_levels)
+ialias_redirect (omp_get_level)
+ialias_redirect (omp_get_ancestor_thread_num)
+ialias_redirect (omp_get_team_size)
+ialias_redirect (omp_get_active_level)
 #endif        
 
 void
@@ -225,3 +234,97 @@ omp_get_wtime_ (void)
 {
   return omp_get_wtime ();
 }
+
+void
+omp_set_schedule_ (const int32_t *kind, const int32_t *modifier)
+{
+  omp_set_schedule (*kind, *modifier);
+}
+
+void
+omp_set_schedule_8_ (const int32_t *kind, const int64_t *modifier)
+{
+  omp_set_schedule (*kind, *modifier);
+}
+
+int32_t
+omp_get_schedule_ (int32_t *kind, int32_t *modifier)
+{
+  omp_sched_t k;
+  int m, r;
+  r = omp_get_schedule (&k, &m);
+  *kind = k;
+  *modifier = m;
+  return r;
+}
+
+int32_t
+omp_get_schedule_8_ (int32_t *kind, int64_t *modifier)
+{
+  omp_sched_t k;
+  int m, r;
+  r = omp_get_schedule (&k, &m);
+  *kind = k;
+  *modifier = m;
+  return r;
+}
+
+int32_t
+omp_get_thread_limit_ (void)
+{
+  return omp_get_thread_limit ();
+}
+
+void
+omp_set_max_active_levels_ (const int32_t *levels)
+{
+  omp_set_max_active_levels (*levels);
+}
+
+void
+omp_set_max_active_levels_8_ (const int64_t *levels)
+{
+  omp_set_max_active_levels (*levels);
+}
+
+int32_t
+omp_get_max_active_levels_ (void)
+{
+  return omp_get_max_active_levels ();
+}
+
+int32_t
+omp_get_level_ (void)
+{
+  return omp_get_level ();
+}
+
+int32_t
+omp_get_ancestor_thread_num_ (const int32_t *level)
+{
+  return omp_get_ancestor_thread_num (*level);
+}
+
+int32_t
+omp_get_ancestor_thread_num_8_ (const int64_t *level)
+{
+  return omp_get_ancestor_thread_num (*level);
+}
+
+int32_t
+omp_get_team_size_ (const int32_t *level)
+{
+  return omp_get_team_size (*level);
+}
+
+int32_t
+omp_get_team_size_8_ (const int64_t *level)
+{
+  return omp_get_team_size (*level);
+}
+
+int32_t
+omp_get_active_level_ (void)
+{
+  return omp_get_active_level ();
+}
--- libgomp/env.c.jj	2007-10-22 23:01:18.000000000 +0200
+++ libgomp/env.c	2007-10-23 19:26:58.000000000 +0200
@@ -13,7 +13,7 @@
    FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
    more details.
 
-   You should have received a copy of the GNU Lesser General Public License 
+   You should have received a copy of the GNU Lesser General Public License
    along with libgomp; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
    MA 02110-1301, USA.  */
@@ -45,8 +45,8 @@ unsigned long gomp_run_sched_chunk = 1;
 unsigned short *gomp_cpu_affinity;
 bool gomp_active_wait_policy = false;
 size_t gomp_cpu_affinity_len;
-unsigned long gomp_max_active_levels_var = -1;
-unsigned long gomp_thread_limit_var = -1;
+unsigned long gomp_max_active_levels_var = INT_MAX;
+unsigned long gomp_thread_limit_var = INT_MAX;
 
 /* Parse the OMP_SCHEDULE environment variable.  */
 
@@ -216,7 +216,7 @@ parse_stacksize (const char *name, unsig
   return false;
 }
 
-/* Parse a boolean value for environment variable NAME and store the 
+/* Parse a boolean value for environment variable NAME and store the
    result in VALUE.  */
 
 static void
@@ -248,7 +248,7 @@ parse_boolean (const char *name, bool *v
     gomp_error ("Invalid value for environment variable %s", name);
 }
 
-/* Parse the OMP_WAIT_POLICY environment variable and store the 
+/* Parse the OMP_WAIT_POLICY environment variable and store the
    result in gomp_active_wait_policy.  */
 
 static void
@@ -451,8 +451,61 @@ omp_get_nested (void)
   return gomp_nest_var;
 }
 
+void
+omp_set_schedule (omp_sched_t kind, int modifier)
+{
+  switch (kind)
+    {
+    case omp_sched_static:
+    case omp_sched_dynamic:
+    case omp_sched_guided:
+      if (modifier < 1)
+	modifier = 1;
+      gomp_run_sched_chunk = modifier;
+      break;
+    case omp_sched_auto:
+      break;
+    default:
+      return;
+    }
+  gomp_run_sched_var = kind;
+}
+
+int
+omp_get_schedule (omp_sched_t *kind, int *modifier)
+{
+  *kind = gomp_run_sched_var;
+  *modifier = gomp_run_sched_chunk;
+  /* FIXME: What is this supposed to return?  */
+  return 0;
+}
+
+int
+omp_get_thread_limit (void)
+{
+  return gomp_thread_limit_var;
+}
+
+void
+omp_set_max_active_levels (int max_levels)
+{
+  if (max_levels > 0)
+    gomp_max_active_levels_var = max_levels;
+}
+
+int
+omp_get_max_active_levels (void)
+{
+  return gomp_max_active_levels_var;
+}
+
 ialias (omp_set_dynamic)
 ialias (omp_set_nested)
 ialias (omp_set_num_threads)
 ialias (omp_get_dynamic)
 ialias (omp_get_nested)
+ialias (omp_set_schedule)
+ialias (omp_get_schedule)
+ialias (omp_get_thread_limit)
+ialias (omp_set_max_active_levels)
+ialias (omp_get_max_active_levels)
--- libgomp/libgomp.map.jj	2007-10-22 22:11:45.000000000 +0200
+++ libgomp/libgomp.map	2007-10-23 18:07:26.000000000 +0200
@@ -55,6 +55,33 @@ OMP_2.0 {
 	omp_get_wtime_;
 } OMP_1.0;
 
+OMP_3.0 {
+  global:
+	omp_set_schedule;
+	omp_set_schedule_;
+	omp_set_schedule_8_;
+	omp_get_schedule;
+	omp_get_schedule_;
+	omp_get_schedule_8_;
+	omp_get_thread_limit;
+	omp_get_thread_limit_;
+	omp_set_max_active_levels;
+	omp_set_max_active_levels_;
+	omp_set_max_active_levels_8_;
+	omp_get_max_active_levels;
+	omp_get_max_active_levels_;
+	omp_get_level;
+	omp_get_level_;
+	omp_get_ancestor_thread_num;
+	omp_get_ancestor_thread_num_;
+	omp_get_ancestor_thread_num_8_;
+	omp_get_team_size;
+	omp_get_team_size_;
+	omp_get_team_size_8_;
+	omp_get_active_level;
+	omp_get_active_level_;
+} OMP_2.0;
+
 GOMP_1.0 {
   global:
 	GOMP_atomic_end;
--- libgomp/testsuite/libgomp.fortran/nested1.f90.jj	2007-10-23 20:44:16.000000000 +0200
+++ libgomp/testsuite/libgomp.fortran/nested1.f90	2007-10-23 21:09:26.000000000 +0200
@@ -0,0 +1,87 @@
+! { dg-do run }
+program nested1
+  use omp_lib
+  integer :: e1, e2, e3, e
+  integer :: tn1, tn2, tn3
+  e1 = 0
+  e2 = 0
+  e3 = 0
+  call omp_set_nested (.true.)
+  call omp_set_dynamic (.false.)
+  if (omp_in_parallel ()) call abort
+  if (omp_get_num_threads ().ne.1) call abort
+  if (omp_get_level ().ne.0) call abort
+  if (omp_get_ancestor_thread_num (0).ne.0) call abort
+  if (omp_get_ancestor_thread_num (-1).ne.-1) call abort
+  if (omp_get_ancestor_thread_num (1).ne.-1) call abort
+  if (omp_get_team_size (0).ne.1) call abort
+  if (omp_get_team_size (-1).ne.-1) call abort
+  if (omp_get_team_size (1).ne.-1) call abort
+  if (omp_get_active_level ().ne.0) call abort
+!$omp parallel num_threads (4) private (e, tn1)
+  e = 0
+  tn1 = omp_get_thread_num ()
+  if (.not.omp_in_parallel ()) e = e + 1
+  if (omp_get_num_threads ().ne.4) e = e + 1
+  if (tn1.lt.0.or.tn1.ge.4) e = e + 1
+  if (omp_get_level ().ne.1) e = e + 1
+  if (omp_get_ancestor_thread_num (0).ne.0) e = e + 1
+  if (omp_get_ancestor_thread_num (1).ne.tn1) e = e + 1
+  if (omp_get_ancestor_thread_num (-1).ne.-1) e = e + 1
+  if (omp_get_ancestor_thread_num (2).ne.-1) e = e + 1
+  if (omp_get_team_size (0).ne.1) e = e + 1
+  if (omp_get_team_size (1).ne.4) e = e + 1
+  if (omp_get_team_size (-1).ne.-1) e = e + 1
+  if (omp_get_team_size (2).ne.-1) e = e + 1
+  if (omp_get_active_level ().ne.1) e = e + 1
+  !$omp atomic
+    e1 = e1 + e
+!$omp parallel num_threads (5) if (.false.) firstprivate (tn1) &
+!$omp& private (e, tn2)
+  e = 0
+  tn2 = omp_get_thread_num ()
+  if (.not.omp_in_parallel ()) e = e + 1
+  if (omp_get_num_threads ().ne.1) e = e + 1
+  if (tn2.ne.0) e = e + 1
+  if (omp_get_level ().ne.2) e = e + 1
+  if (omp_get_ancestor_thread_num (0).ne.0) e = e + 1
+  if (omp_get_ancestor_thread_num (1).ne.tn1) e = e + 1
+  if (omp_get_ancestor_thread_num (2).ne.tn2) e = e + 1
+  if (omp_get_ancestor_thread_num (-1).ne.-1) e = e + 1
+  if (omp_get_ancestor_thread_num (3).ne.-1) e = e + 1
+  if (omp_get_team_size (0).ne.1) e = e + 1
+  if (omp_get_team_size (1).ne.4) e = e + 1
+  if (omp_get_team_size (2).ne.1) e = e + 1
+  if (omp_get_team_size (-1).ne.-1) e = e + 1
+  if (omp_get_team_size (3).ne.-1) e = e + 1
+  if (omp_get_active_level ().ne.1) e = e + 1
+  !$omp atomic
+    e2 = e2 + e
+!$omp parallel num_threads (2) firstprivate (tn1, tn2) &
+!$omp& private (e, tn3)
+  e = 0
+  tn3 = omp_get_thread_num ()
+  if (.not.omp_in_parallel ()) e = e + 1
+  if (omp_get_num_threads ().ne.2) e = e + 1
+  if (tn3.lt.0.or.tn3.ge.2) e = e + 1
+  if (omp_get_level ().ne.3) e = e + 1
+  if (omp_get_ancestor_thread_num (0).ne.0) e = e + 1
+  if (omp_get_ancestor_thread_num (1).ne.tn1) e = e + 1
+  if (omp_get_ancestor_thread_num (2).ne.tn2) e = e + 1
+  if (omp_get_ancestor_thread_num (3).ne.tn3) e = e + 1
+  if (omp_get_ancestor_thread_num (-1).ne.-1) e = e + 1
+  if (omp_get_ancestor_thread_num (4).ne.-1) e = e + 1
+  if (omp_get_team_size (0).ne.1) e = e + 1
+  if (omp_get_team_size (1).ne.4) e = e + 1
+  if (omp_get_team_size (2).ne.1) e = e + 1
+  if (omp_get_team_size (3).ne.2) e = e + 1
+  if (omp_get_team_size (-1).ne.-1) e = e + 1
+  if (omp_get_team_size (4).ne.-1) e = e + 1
+  if (omp_get_active_level ().ne.2) e = e + 1
+  !$omp atomic
+    e3 = e3 + e
+!$omp end parallel
+!$omp end parallel
+!$omp end parallel
+  if (e1.ne.0.or.e2.ne.0.or.e3.ne.0) call abort
+end program nested1
--- libgomp/testsuite/libgomp.fortran/lib4.f90.jj	2007-10-23 21:29:04.000000000 +0200
+++ libgomp/testsuite/libgomp.fortran/lib4.f90	2007-10-23 21:35:58.000000000 +0200
@@ -0,0 +1,16 @@
+! { dg-do run }
+
+program lib4
+  use omp_lib
+  integer (omp_sched_kind) :: kind
+  integer :: modifier
+  call omp_set_schedule (omp_sched_static, 32)
+  call omp_get_schedule (kind, modifier)
+  if (kind.ne.omp_sched_static.or.modifier.ne.32) call abort
+  call omp_set_schedule (omp_sched_dynamic, 4)
+  call omp_get_schedule (kind, modifier)
+  if (kind.ne.omp_sched_dynamic.or.modifier.ne.4) call abort
+  if (omp_get_thread_limit ().lt.0) call abort
+  call omp_set_max_active_levels (6)
+  if (omp_get_max_active_levels ().ne.6) call abort
+end program lib4
--- libgomp/testsuite/libgomp.c/lib-2.c.jj	2007-10-23 21:28:15.000000000 +0200
+++ libgomp/testsuite/libgomp.c/lib-2.c	2007-10-23 21:28:06.000000000 +0200
@@ -0,0 +1,25 @@
+#include <stdlib.h>
+#include <omp.h>
+
+int
+main (void)
+{
+  omp_sched_t kind;
+  int modifier;
+
+  omp_set_schedule (omp_sched_static, 32);
+  omp_get_schedule (&kind, &modifier);
+  if (kind != omp_sched_static || modifier != 32)
+    abort ();
+  omp_set_schedule (omp_sched_guided, 4);
+  omp_get_schedule (&kind, &modifier);
+  if (kind != omp_sched_guided || modifier != 4)
+    abort ();
+  if (omp_get_thread_limit () < 0)
+    abort ();
+  omp_set_max_active_levels (6);
+  if (omp_get_max_active_levels () != 6)
+    abort ();
+
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/nested-3.c.jj	2007-10-23 20:37:09.000000000 +0200
+++ libgomp/testsuite/libgomp.c/nested-3.c	2007-10-23 21:13:26.000000000 +0200
@@ -0,0 +1,89 @@
+#include <omp.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+main (void)
+{
+  int e[3];
+
+  memset (e, '\0', sizeof (e));
+  omp_set_nested (1);
+  omp_set_dynamic (0);
+  if (omp_in_parallel ()
+      || omp_get_level () != 0
+      || omp_get_ancestor_thread_num (0) != 0
+      || omp_get_ancestor_thread_num (-1) != -1
+      || omp_get_ancestor_thread_num (1) != -1
+      || omp_get_team_size (0) != 1
+      || omp_get_team_size (-1) != -1
+      || omp_get_team_size (1) != -1
+      || omp_get_active_level () != 0)
+    abort ();
+#pragma omp parallel num_threads (4)
+  {
+    int tn1 = omp_get_thread_num ();
+    if (omp_in_parallel () != 1
+	|| omp_get_num_threads () != 4
+	|| tn1 >= 4 || tn1 < 0
+	|| omp_get_level () != 1
+	|| omp_get_ancestor_thread_num (0) != 0
+	|| omp_get_ancestor_thread_num (1) != tn1
+	|| omp_get_ancestor_thread_num (-1) != -1
+	|| omp_get_ancestor_thread_num (2) != -1
+	|| omp_get_team_size (0) != 1
+	|| omp_get_team_size (1) != omp_get_num_threads ()
+	|| omp_get_team_size (-1) != -1
+	|| omp_get_team_size (2) != -1
+	|| omp_get_active_level () != 1)
+      #pragma omp atomic
+	e[0] += 1;
+    #pragma omp parallel if (0) num_threads(5) firstprivate(tn1)
+    {
+      int tn2 = omp_get_thread_num ();
+      if (omp_in_parallel () != 1
+	  || omp_get_num_threads () != 1
+	  || tn2 != 0
+	  || omp_get_level () != 2
+	  || omp_get_ancestor_thread_num (0) != 0
+	  || omp_get_ancestor_thread_num (1) != tn1
+	  || omp_get_ancestor_thread_num (2) != tn2
+	  || omp_get_ancestor_thread_num (-1) != -1
+	  || omp_get_ancestor_thread_num (3) != -1
+	  || omp_get_team_size (0) != 1
+	  || omp_get_team_size (1) != 4
+	  || omp_get_team_size (2) != 1
+	  || omp_get_team_size (-1) != -1
+	  || omp_get_team_size (3) != -1
+	  || omp_get_active_level () != 1)
+	#pragma omp atomic
+	  e[1] += 1;
+      #pragma omp parallel num_threads(2) firstprivate(tn1, tn2)
+      {
+	int tn3 = omp_get_thread_num ();
+	if (omp_in_parallel () != 1
+	    || omp_get_num_threads () != 2
+	    || tn3 > 1 || tn3 < 0
+	    || omp_get_level () != 3
+	    || omp_get_ancestor_thread_num (0) != 0
+	    || omp_get_ancestor_thread_num (1) != tn1
+	    || omp_get_ancestor_thread_num (2) != tn2
+	    || omp_get_ancestor_thread_num (3) != tn3
+	    || omp_get_ancestor_thread_num (-1) != -1
+	    || omp_get_ancestor_thread_num (4) != -1
+	    || omp_get_team_size (0) != 1
+	    || omp_get_team_size (1) != 4
+	    || omp_get_team_size (2) != 1
+	    || omp_get_team_size (3) != 2
+	    || omp_get_team_size (-1) != -1
+	    || omp_get_team_size (4) != -1
+	    || omp_get_active_level () != 2)
+	  #pragma omp atomic
+	    e[2] += 1;
+      }
+    }
+  }
+  if (e[0] || e[1] || e[2])
+    abort ();
+  return 0;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]