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]

Re: [gomp4] OpenACC wait directive


On 10/06/2014 03:56 AM, Ilmir Usmanov wrote:

> Otherwise, Fortran part looks good for me.

Thanks for the review again! I applied this patch to gomp-4_0-branch now
that the middle end pieces are in place.

Thanks,
Cesar
2014-10-31  Cesar Philippidis  <cesar@codesourcery.com>

	gcc/fortran/
	* gfortran.h (struct gfc_omp_clauses): Remove non_clause_wait_expr.
	* dump-parse-tree.c (show_omp_clauses): Likewise.
	* openmp.c (gfc_free_omp_clauses): Likewise.
	(gfc_match_omp_clauses): Update handling of async.
	(OACC_WAIT_CLAUSE_MASK): New define.
	(gfc_match_oacc_wait): Make the wait directive comply with OpenACC 2.0.
	(resolve_omp_clauses): Use resolve_oacc_scalar_in_expr inspect
	arguments to the wait clause.
	(resolve_oacc_wait): Remove.
	(gfc_resolve_oacc_directive): Handle EXEC_OACC_WAIT with
	resolve_omp_clauses.
	* trans-openmp.c (gfc_trans_omp_clauses): Update handling of OpenACC
	wait arguments.
	(gfc_trans_oacc_executable_directive): Remove EXEC_OACC_WAIT.
	(gfc_trans_oacc_wait_directive): New function.
	(gfc_trans_oacc_directive): Use it.

	gcc/testsuite/
	* gfortran.dg/goacc/asyncwait-1.f95: New test.
	* gfortran.dg/goacc/asyncwait-2.f95: New test.
	* gfortran.dg/goacc/asyncwait-3.f95: New test.
	* gfortran.dg/goacc/asyncwait-4.f95: New test.

	libgomp
	* testsuite/libgomp.oacc-fortran/asyncwait-1.f90: New test.
	* testsuite/libgomp.oacc-fortran/asyncwait-2.f90: New test.
	* testsuite/libgomp.oacc-fortran/asyncwait-3.f90: New test.


diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
index d7f2182..f85f6b6 100644
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -1173,12 +1173,6 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses)
 	  fputc (')', dumpfile);
 	}
     }
-  if (omp_clauses->non_clause_wait_expr)
-    {
-      fputc ('(', dumpfile);
-      show_expr (omp_clauses->non_clause_wait_expr);
-      fputc (')', dumpfile);
-    }
   if (omp_clauses->sched_kind != OMP_SCHED_NONE)
     {
       const char *type;
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 4b1724b..adfa1b2 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1264,7 +1264,6 @@ typedef struct gfc_omp_clauses
   struct gfc_expr *num_gangs_expr;
   struct gfc_expr *num_workers_expr;
   struct gfc_expr *vector_length_expr;
-  struct gfc_expr *non_clause_wait_expr;
   gfc_expr_list *wait_list;
   gfc_expr_list *tile_list;
   unsigned async:1, gang:1, worker:1, vector:1, seq:1, independent:1;
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 4a48335..c158128 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -83,7 +83,6 @@ gfc_free_omp_clauses (gfc_omp_clauses *c)
   gfc_free_expr (c->num_gangs_expr);
   gfc_free_expr (c->num_workers_expr);
   gfc_free_expr (c->vector_length_expr);
-  gfc_free_expr (c->non_clause_wait_expr);
   for (i = 0; i < OMP_LIST_NUM; i++)
     gfc_free_omp_namelist (c->lists[i]);
   gfc_free_expr_list (c->wait_list);
@@ -496,10 +495,15 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, unsigned long long mask,
 	if (gfc_match ("async") == MATCH_YES)
 	  {
 	    c->async = true;
-	    if (gfc_match (" ( %e )", &c->async_expr) == MATCH_YES)
-	      needs_space = false;
-	    else
-	      needs_space = true;
+	    needs_space = false;
+	    if (gfc_match (" ( %e )", &c->async_expr) != MATCH_YES)
+	      {
+		c->async_expr = gfc_get_constant_expr (BT_INTEGER,
+						       gfc_default_integer_kind,
+						      &gfc_current_locus);
+		/* TODO XXX: FIX -1 (acc_async_noval).  */
+		mpz_set_si (c->async_expr->value.integer, -1);
+	      }
 	    continue;
 	  }
       if ((mask & OMP_CLAUSE_GANG) && !c->gang)
@@ -1168,6 +1172,8 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, unsigned long long mask,
 #define OACC_EXIT_DATA_CLAUSES \
   (OMP_CLAUSE_IF | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT | OMP_CLAUSE_COPYOUT \
    | OMP_CLAUSE_DELETE)
+#define OACC_WAIT_CLAUSES \
+  (OMP_CLAUSE_ASYNC)
 
 
 match
@@ -1328,8 +1334,38 @@ match
 gfc_match_oacc_wait (void)
 {
   gfc_omp_clauses *c = gfc_get_omp_clauses ();
-  gfc_match (" ( %e )", &c->non_clause_wait_expr);
+  gfc_expr_list *wait_list = NULL, *el;
+
+  match_oacc_expr_list (" (", &wait_list, true);
+  gfc_match_omp_clauses (&c, OACC_WAIT_CLAUSES, false, false, true);
+
+  if (gfc_match_omp_eos () != MATCH_YES)
+    {
+      gfc_error ("Unexpected junk in !$ACC WAIT at %C");
+      return MATCH_ERROR;
+    }
+
+  if (wait_list)
+    for (el = wait_list; el; el = el->next)
+      {
+	if (el->expr == NULL)
+	  {
+	    gfc_error ("Invalid argument to $!ACC WAIT at %L",
+		       &wait_list->expr->where);
+	    return MATCH_ERROR;
+	  }
+
+	if (!gfc_resolve_expr (el->expr)
+	    || el->expr->ts.type != BT_INTEGER || el->expr->rank != 0
+	    || el->expr->expr_type != EXPR_CONSTANT)
+	  {
+	    gfc_error ("WAIT clause at %L requires a scalar INTEGER expression",
+		       &el->expr->where);
 
+	    return MATCH_ERROR;
+	  }
+      }
+  c->wait_list = wait_list;
   new_st.op = EXEC_OACC_WAIT;
   new_st.ext.omp_clauses = c;
   return MATCH_YES;
@@ -3343,7 +3379,7 @@ resolve_omp_clauses (gfc_code *code, locus *where,
   if (omp_clauses->wait)
     if (omp_clauses->wait_list)
       for (el = omp_clauses->wait_list; el; el = el->next)
-	resolve_oacc_positive_int_expr (el->expr, "WAIT");
+	resolve_oacc_scalar_int_expr (el->expr, "WAIT");
 }
 
 
@@ -4490,16 +4526,6 @@ resolve_oacc_cache (gfc_code *code)
 }
 
 
-static void
-resolve_oacc_wait (gfc_code *code)
-{
-  gfc_expr_list* el;
-
-  for (el = code->ext.omp_clauses->wait_list; el; el = el->next)
-    resolve_oacc_positive_int_expr (el->expr, "WAIT");
-}
-
-
 void
 gfc_resolve_oacc_declare (gfc_namespace *ns)
 {
@@ -4573,6 +4599,7 @@ gfc_resolve_oacc_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
     case EXEC_OACC_UPDATE:
     case EXEC_OACC_ENTER_DATA:
     case EXEC_OACC_EXIT_DATA:
+    case EXEC_OACC_WAIT:
       resolve_omp_clauses (code, &code->loc, code->ext.omp_clauses, NULL,
 			   true);
       break;
@@ -4584,9 +4611,6 @@ gfc_resolve_oacc_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
     case EXEC_OACC_CACHE:
       resolve_oacc_cache (code);
       break;
-    case EXEC_OACC_WAIT:
-      resolve_oacc_wait (code);
-      break;
     default:
       break;
     }
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 987be4d..165282c 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -2555,6 +2555,21 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
       c = build_omp_clause (where.lb->location, OMP_CLAUSE_INDEPENDENT);
       omp_clauses = gfc_trans_add_clause (c, omp_clauses);
     }
+  if (clauses->wait_list)
+    {
+      gfc_expr_list *el;
+      tree list = NULL;
+
+      for (el = clauses->wait_list; el; el = el->next)
+	{
+	  c = build_omp_clause (where.lb->location, OMP_CLAUSE_WAIT);
+	  OMP_CLAUSE_DECL (c) = gfc_convert_expr_to_tree (block, el->expr);
+	  OMP_CLAUSE_CHAIN (c) = list;
+	  list = c;
+	}
+
+      omp_clauses = list;
+    }
   if (clauses->num_gangs_expr)
     {
       tree num_gangs_var = 
@@ -2627,14 +2642,6 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 	  omp_clauses = gfc_trans_add_clause (c, omp_clauses);
 	}
     }
-  if (clauses->non_clause_wait_expr)
-    {
-      tree wait_var = 
-	  gfc_convert_expr_to_tree (block, clauses->non_clause_wait_expr);
-      c = build_omp_clause (where.lb->location, OMP_CLAUSE_WAIT);
-      OMP_CLAUSE_WAIT_EXPR (c)= wait_var;
-      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
-    }
 
   return nreverse (omp_clauses);
 }
@@ -2700,7 +2707,7 @@ gfc_trans_oacc_construct (gfc_code *code)
   return gfc_finish_block (&block);
 }
 
-/* update, enter_data, exit_data, wait, cache. */
+/* update, enter_data, exit_data, cache. */
 static tree 
 gfc_trans_oacc_executable_directive (gfc_code *code)
 {
@@ -2738,6 +2745,44 @@ gfc_trans_oacc_executable_directive (gfc_code *code)
   return gfc_finish_block (&block);
 }
 
+static tree
+gfc_trans_oacc_wait_directive (gfc_code *code)
+{
+  stmtblock_t block;
+  tree stmt, t;
+  vec<tree, va_gc> *args;
+  int nparms = 0;
+  gfc_expr_list *el;
+  gfc_omp_clauses *clauses = code->ext.omp_clauses;
+  location_t loc = input_location;
+
+  for (el = clauses->wait_list; el; el = el->next)
+    nparms++;
+
+  vec_alloc (args, nparms + 2);
+  stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT);
+
+  gfc_start_block (&block);
+
+  if (clauses->async_expr)
+    t = gfc_convert_expr_to_tree (&block, clauses->async_expr);
+  else
+    t = build_int_cst (integer_type_node, -2);
+
+  args->quick_push (t);
+  args->quick_push (build_int_cst (integer_type_node, nparms));
+
+  for (el = clauses->wait_list; el; el = el->next)
+    args->quick_push (gfc_convert_expr_to_tree (&block, el->expr));
+
+  stmt = build_call_expr_loc_vec (loc, stmt, args);
+  gfc_add_expr_to_block (&block, stmt);
+
+  vec_free (args);
+
+  return gfc_finish_block (&block);
+}
+
 static tree gfc_trans_omp_sections (gfc_code *, gfc_omp_clauses *);
 static tree gfc_trans_omp_workshare (gfc_code *, gfc_omp_clauses *);
 
@@ -4343,11 +4388,12 @@ gfc_trans_oacc_directive (gfc_code *code)
       return gfc_trans_omp_do (code, code->op, NULL, code->ext.omp_clauses,
 			       NULL);
     case EXEC_OACC_UPDATE:
-    case EXEC_OACC_WAIT:
     case EXEC_OACC_CACHE:
     case EXEC_OACC_ENTER_DATA:
     case EXEC_OACC_EXIT_DATA:
       return gfc_trans_oacc_executable_directive (code);
+    case EXEC_OACC_WAIT:
+      return gfc_trans_oacc_wait_directive (code);
     default:
       gcc_unreachable ();
     }
diff --git a/gcc/testsuite/gfortran.dg/goacc/asyncwait-1.f95 b/gcc/testsuite/gfortran.dg/goacc/asyncwait-1.f95
new file mode 100644
index 0000000..d630d38
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/asyncwait-1.f95
@@ -0,0 +1,91 @@
+! { dg-do compile }
+
+program asyncwait
+  integer, parameter :: N = 64
+  real, allocatable :: a(:), b(:)
+  integer i
+
+  allocate (a(N))
+  allocate (b(N))
+
+  a(:) = 3.0
+  b(:) = 0.0
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) async (1 2) ! { dg-error "Unclassifiable OpenACC directive" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) async (1,) ! { dg-error "Unclassifiable OpenACC directive" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) async (,1) ! { dg-error "Invalid character in name" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) async (1,2,) ! { dg-error "Unclassifiable OpenACC directive" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) async (1,2 3) ! { dg-error "Unclassifiable OpenACC directive" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) async (1,2,,) ! { dg-error "Unclassifiable OpenACC directive" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) async (1  ! { dg-error "Unclassifiable OpenACC directive" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) async (*) ! { dg-error "Invalid character in name at" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) async (a) ! { dg-error "ASYNC clause at \\\(1\\\) requires a scalar INTEGER expression" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) async (N)
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) async (1.0) ! { dg-error "ASYNC clause at \\\(1\\\) requires a scalar INTEGER expression" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) async () ! { dg-error "Invalid character in name at " }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) async
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel
+end program asyncwait
diff --git a/gcc/testsuite/gfortran.dg/goacc/asyncwait-2.f95 b/gcc/testsuite/gfortran.dg/goacc/asyncwait-2.f95
new file mode 100644
index 0000000..db0ce1f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/asyncwait-2.f95
@@ -0,0 +1,91 @@
+! { dg-do compile }
+
+program asyncwait
+  integer, parameter :: N = 64
+  real, allocatable :: a(:), b(:)
+  integer i
+
+  allocate (a(N))
+  allocate (b(N))
+
+  a(:) = 3.0
+  b(:) = 0.0
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) wait (1 2) ! { dg-error "Syntax error in OpenACC expression list" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) wait (1,) ! { dg-error "Syntax error in OpenACC expression list" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) wait (,1) ! { dg-error "Syntax error in OpenACC expression list" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) wait (1,2,) ! { dg-error "Syntax error in OpenACC expression list" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) wait (1,2 3) ! { dg-error "Syntax error in OpenACC expression list" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) wait (1,2,,) ! { dg-error "Syntax error in OpenACC expression list" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) wait (1 ! { dg-error "Syntax error in OpenACC expression list" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) wait (*) ! { dg-error "Syntax error in OpenACC expression list" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) wait (a) ! { dg-error "WAIT clause at \\\(1\\\) requires a scalar INTEGER expression" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) wait (N)
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) wait (1.0) ! { dg-error "WAIT clause at \\\(1\\\) requires a scalar INTEGER expression" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) wait () ! { dg-error "Syntax error in OpenACC expression list" }
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel ! { dg-error "Unexpected \\\!\\\$ACC END PARALLEL" }
+
+  !$acc parallel copyin (a(1:N)) copy (b(1:N)) wait
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel
+end program asyncwait
diff --git a/gcc/testsuite/gfortran.dg/goacc/asyncwait-3.f95 b/gcc/testsuite/gfortran.dg/goacc/asyncwait-3.f95
new file mode 100644
index 0000000..32c11de
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/asyncwait-3.f95
@@ -0,0 +1,41 @@
+! { dg-do compile }
+
+program asyncwait
+  integer, parameter :: N = 64
+  real, allocatable :: a(:), b(:)
+  integer i
+
+  allocate (a(N))
+  allocate (b(N))
+
+  a(:) = 3.0
+  b(:) = 0.0
+
+  !$acc wait (1 2) ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait (1,) ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait (,1) ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait (1, 2, ) ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait (1, 2, ,) ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait (1 ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait (1, *) ! { dg-error "Invalid argument to \\\$\\\!ACC WAIT" }
+
+  !$acc wait (1, a) ! { dg-error "WAIT clause at \\\(1\\\) requires a scalar INTEGER expression" }
+
+  !$acc wait (a) ! { dg-error "WAIT clause at \\\(1\\\) requires a scalar INTEGER expression" }
+
+  !$acc wait (N) 
+
+  !$acc wait (1.0) ! { dg-error "WAIT clause at \\\(1\\\) requires a scalar INTEGER expression" }
+
+  !$acc wait 1 ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait N ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait (1)
+end program asyncwait
diff --git a/gcc/testsuite/gfortran.dg/goacc/asyncwait-4.f95 b/gcc/testsuite/gfortran.dg/goacc/asyncwait-4.f95
new file mode 100644
index 0000000..cd64ef3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/asyncwait-4.f95
@@ -0,0 +1,37 @@
+! { dg-do compile }
+
+program asyncwait
+  integer, parameter :: N = 64
+  real, allocatable :: a(:), b(:)
+  integer i
+
+  allocate (a(N))
+  allocate (b(N))
+
+  a(:) = 3.0
+  b(:) = 0.0
+
+  !$acc wait async (1 2) ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait async (1,) ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait async (,1) ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait async (1, 2, ) ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait async (1, 2, ,) ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait async (1 ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait async (1, *) ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait async (1, a) ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+
+  !$acc wait async (a) ! { dg-error "ASYNC clause at \\\(1\\\) requires a scalar INTEGER expression" }
+
+  !$acc wait async (N)
+
+  !$acc wait async (1.0) ! { dg-error "ASYNC clause at \\\(1\\\) requires a scalar INTEGER expression" }
+
+  !$acc wait async 1 ! { dg-error "Unexpected junk in \\\!\\\$ACC WAIT at" }
+end program asyncwait
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/asyncwait-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/asyncwait-1.f90
new file mode 100644
index 0000000..b6e637b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/asyncwait-1.f90
@@ -0,0 +1,135 @@
+! { dg-do run }
+
+program asyncwait
+  integer, parameter :: N = 64
+  real, allocatable :: a(:), b(:), c(:), d(:), e(:)
+  integer i
+
+  allocate (a(N))
+  allocate (b(N))
+  allocate (c(N))
+  allocate (d(N))
+  allocate (e(N))
+
+  a(:) = 3.0
+  b(:) = 0.0
+
+  !$acc data copy (a(1:N)) copy (b(1:N))
+
+  !$acc parallel async
+  !$acc loop
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel
+
+  !$acc wait
+  !$acc end data
+
+  do i = 1, N
+     if (a(i) .ne. 3.0) call abort
+     if (b(i) .ne. 3.0) call abort
+  end do
+
+  a(:) = 2.0
+  b(:) = 0.0
+
+  !$acc data copy (a(1:N)) copy (b(1:N))
+
+  !$acc parallel async (1)
+  !$acc loop
+  do i = 1, N
+     b(i) = a(i)
+  end do
+  !$acc end parallel
+
+  !$acc wait (1)
+  !$acc end data
+
+  do i = 1, N
+     if (a(i) .ne. 2.0) call abort
+     if (b(i) .ne. 2.0) call abort
+  end do
+
+  a(:) = 3.0
+  b(:) = 0.0
+  c(:) = 0.0
+  d(:) = 0.0
+
+  !$acc data copy (a(1:N)) copy (b(1:N)) copy (c(1:N)) copy (d(1:N))
+
+  !$acc parallel async (1)
+  do i = 1, N
+     b(i) = (a(i) * a(i) * a(i)) / a(i)
+  end do
+  !$acc end parallel
+
+  !$acc parallel async (1)
+  do i = 1, N
+     c(i) = (a(i) * 4) / a(i)
+  end do
+  !$acc end parallel
+
+  !$acc parallel async (1)
+  !$acc loop
+  do i = 1, N
+     d(i) = ((a(i) * a(i) + a(i)) / a(i)) - a(i)
+  end do
+  !$acc end parallel
+
+  !$acc wait (1)
+  !$acc end data
+
+  do i = 1, N
+     if (a(i) .ne. 3.0) call abort
+     if (b(i) .ne. 9.0) call abort
+     if (c(i) .ne. 4.0) call abort
+     if (d(i) .ne. 1.0) call abort
+  end do
+
+  a(:) = 2.0
+  b(:) = 0.0
+  c(:) = 0.0
+  d(:) = 0.0
+  e(:) = 0.0
+
+  !$acc data copy (a(1:N), b(1:N), c(1:N), d(1:N), e(1:N))
+
+  !$acc parallel async (1)
+  do i = 1, N
+     b(i) = (a(i) * a(i) * a(i)) / a(i)
+  end do
+  !$acc end parallel
+
+  !$acc parallel async (1)
+  !$acc loop
+  do i = 1, N
+     c(i) = (a(i) * 4) / a(i)
+  end do
+  !$acc end parallel
+
+  !$acc parallel async (1)
+  !$acc loop
+  do i = 1, N
+     d(i) = ((a(i) * a(i) + a(i)) / a(i)) - a(i)
+  end do
+  !$acc end parallel
+
+  !$acc parallel wait (1) async (1)
+  !$acc loop
+  do i = 1, N
+     e(i) = a(i) + b(i) + c(i) + d(i)
+  end do
+  !$acc end parallel
+
+  !$acc wait (1)
+  !$acc end data
+
+  do i = 1, N
+     if (a(i) .ne. 2.0) call abort
+     if (b(i) .ne. 4.0) call abort
+     if (c(i) .ne. 4.0) call abort
+     if (d(i) .ne. 1.0) call abort
+     if (e(i) .ne. 11.0) call abort
+  end do
+end program asyncwait
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/asyncwait-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/asyncwait-2.f90
new file mode 100644
index 0000000..bade52b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/asyncwait-2.f90
@@ -0,0 +1,40 @@
+! { dg-do run }
+
+program parallel_wait
+  integer, parameter :: N = 64
+  real, allocatable :: a(:), b(:), c(:)
+  integer i
+
+  allocate (a(N))
+  allocate (b(N))
+  allocate (c(N))
+
+  !$acc parallel async (0)
+  !$acc loop
+  do i = 1, N
+    a(i) = 1
+  end do
+  !$acc end parallel
+
+  !$acc parallel async (1)
+  !$acc loop
+  do i = 1, N
+    b(i) = 1
+  end do
+  !$acc end parallel
+
+  !$acc parallel wait (0, 1)
+  !$acc loop
+  do i = 1, N
+    c(i) = a(i) + b(i)
+  end do
+  !$acc end parallel
+
+  do i = 1, N
+    if (c(i) .ne. 2.0) call abort
+  end do
+  
+  deallocate (a)
+  deallocate (b)
+  deallocate (c)
+end program parallel_wait
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/asyncwait-3.f90 b/libgomp/testsuite/libgomp.oacc-fortran/asyncwait-3.f90
new file mode 100644
index 0000000..d48dc11
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/asyncwait-3.f90
@@ -0,0 +1,42 @@
+! { dg-do run }
+
+program parallel_wait
+  integer, parameter :: N = 64
+  real, allocatable :: a(:), b(:), c(:)
+  integer i
+
+  allocate (a(N))
+  allocate (b(N))
+  allocate (c(N))
+
+  !$acc parallel async (0)
+  !$acc loop
+  do i = 1, N
+    a(i) = 1
+  end do
+  !$acc end parallel
+
+  !$acc parallel async (1)
+  !$acc loop
+  do i = 1, N
+    b(i) = 1
+  end do
+  !$acc end parallel
+
+  !$acc wait (0, 1)
+
+  !$acc parallel
+  !$acc loop
+  do i = 1, N
+    c(i) = a(i) + b(i)
+  end do
+  !$acc end parallel
+
+  do i = 1, N
+    if (c(i) .ne. 2.0) call abort
+  end do
+  
+  deallocate (a)
+  deallocate (b)
+  deallocate (c)
+end program parallel_wait

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