diff mbox

[gomp4] OpenACC wait directive

Message ID 5421F45A.3030001@codesourcery.com
State New
Headers show

Commit Message

Cesar Philippidis Sept. 23, 2014, 10:29 p.m. UTC
This patch adds support for the async clause in the wait directive in
fortran. It should be pretty straight forward. The fortran FE already
supports the wait directive, but the async clause was introduced to the
wait directive in OpenACC 2.0 and that was missing in gomp-4_0-branch.
Is this OK for gomp-4_0-branch? Note that this patch doesn't actually
implement the async or wait clause in the middle end yet, because that
requires additional runtime support.

Thanks,
Cesar

Comments

Ilmir Usmanov Sept. 24, 2014, 7:18 a.m. UTC | #1
Hi Cesar!

Thank you for the patch!

On 24.09.2014 02:29, Cesar Philippidis wrote:
> This patch adds support for the async clause in the wait directive in
> fortran. It should be pretty straight forward. The fortran FE already
> supports the wait directive, but the async clause was introduced to the
> wait directive in OpenACC 2.0 and that was missing in gomp-4_0-branch.
Yes, I've mostly focused on spec. ver. 1.0.

> Is this OK for gomp-4_0-branch?
No, it isn't. According to the spec and this presentation:
http://www.pgroup.com/lit/presentations/cea-3.pdf (See slide 1-35)
it is possible to write construction like:
!$acc wait(1) async(2)
However, your patch doesn't support this. Also, don't forget to check 
whether a queue waits itself (for example, wait(1) async(1)).
In addition, it breaks current support of the directive (for example, 
wait(1)).

> Note that this patch doesn't actually
> implement the async or wait clause in the middle end yet, because that
> requires additional runtime support.
>
> Thanks,
> Cesar
diff mbox

Patch

2014-09-23  Cesar Philippidis  <cesar@codesourcery.com>

	gcc/fortran/
	* openmp.c (OACC_WAIT_CLAUSES): New mask.
	(gfc_match_oacc_wait): Use it.
	(resolve_oacc_wait): Remove.
	(gfc_resolve_oacc_directive): Update handling of EXEC_OACC_WAIT.

	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.


diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index ce94a5c..a287b60 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -1168,6 +1168,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,7 +1330,9 @@  match
 gfc_match_oacc_wait (void)
 {
   gfc_omp_clauses *c = gfc_get_omp_clauses ();
-  gfc_match (" ( %e )", &c->non_clause_wait_expr);
+  if (gfc_match_omp_clauses (&c, OACC_WAIT_CLAUSES, false, false, true)
+      != MATCH_YES)
+    return MATCH_ERROR;
 
   new_st.op = EXEC_OACC_WAIT;
   new_st.ext.omp_clauses = c;
@@ -4490,16 +4494,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 +4567,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 +4579,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/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..3dca142
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/asyncwait-3.f95
@@ -0,0 +1,39 @@ 
+! { 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 "Unclassifiable OpenACC directive" }
+
+  !$acc wait (1,) ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait (,1) ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait (1, 2, ) ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait (1, 2, ,) ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait (1 ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait (1, *) ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait (1, a) ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait (a) ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait (N) ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait (1.0) ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait 1 ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait N ! { dg-error "Unclassifiable OpenACC directive" }
+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..a720cda
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/asyncwait-4.f95
@@ -0,0 +1,38 @@ 
+! { 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 "Unclassifiable OpenACC directive" }
+
+  !$acc wait async (1,) ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait async (,1) ! { dg-error "Invalid character in name" }
+
+  !$acc wait async (1, 2, ) ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait async (1, 2, ,) ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait async (1 ! { dg-error "Unclassifiable OpenACC directive" }
+!$acc wait async (1, *) ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$acc wait async (1, a) ! { dg-error "Unclassifiable OpenACC directive" }
+
+  !$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 "Unclassifiable OpenACC directive" }
+
+  !$acc wait async N ! { dg-error "Unclassifiable OpenACC directive" }
+end program asyncwait