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 <ce...@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