Re: [gomp4] add support for derived types in ACC UPDATE
On 01/30/2017 02:08 AM, Thomas Schwinge wrote: > Hi Cesar! > > On Thu, 10 Nov 2016 09:38:33 -0800, Cesar Philippidis >wrote: >> This patch has been committed to gomp-4_0-branch. > >> --- a/gcc/fortran/openmp.c >> +++ b/gcc/fortran/openmp.c > >> @@ -242,7 +243,8 @@ gfc_match_omp_variable_list (const char *str, >> gfc_omp_namelist **list, >> case MATCH_YES: >>gfc_expr *expr; >>expr = NULL; >> - if (allow_sections && gfc_peek_ascii_char () == '(') >> + if (allow_sections && gfc_peek_ascii_char () == '(' >> + || allow_derived && gfc_peek_ascii_char () == '%') >> { >>gfc_current_locus = cur_loc; >>m = gfc_match_variable (, 0); > > [...]/source-gcc/gcc/fortran/openmp.c: In function 'match > {+gfc_match_omp_variable_list(const char*, gfc_omp_namelist**, bool, bool*, > gfc_omp_namelist***, bool, bool)':+} > [...]/source-gcc/gcc/fortran/openmp.c:246:23: warning: suggest > parentheses around '&&' within '||' [-Wparentheses] > if (allow_sections && gfc_peek_ascii_char () == '(' >^ > >> --- a/gcc/fortran/trans-openmp.c >> +++ b/gcc/fortran/trans-openmp.c >> @@ -1938,7 +1938,66 @@ gfc_trans_omp_clauses_1 (stmtblock_t *block, >> gfc_omp_clauses *clauses, >>tree decl = gfc_get_symbol_decl (n->sym); >>if (DECL_P (decl)) >> TREE_ADDRESSABLE (decl) = 1; >> - if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL) >> + /* Handle derived-typed members for OpenACC Update. */ >> + if (n->sym->ts.type == BT_DERIVED >> + && n->expr != NULL && n->expr->ref != NULL >> + && (n->expr->ref->next == NULL >> + || (n->expr->ref->next != NULL >> + && n->expr->ref->next->type == REF_ARRAY >> + && n->expr->ref->next->u.ar.type == AR_FULL))) >> +{ >> + gfc_ref *ref = n->expr->ref; >> + tree orig_decl = decl; > > [...]/source-gcc/gcc/fortran/trans-openmp.c: In function 'tree_node* > gfc_trans_omp_clauses_1(stmtblock_t*, gfc_omp_clauses*, locus, bool)': > [...]/source-gcc/gcc/fortran/trans-openmp.c:1947:10: warning: unused > variable 'orig_decl' [-Wunused-variable] > tree orig_decl = decl; > ^ Not sure why this wasn't caught with a bootstrap build. Anyway, I've the attached patch to gomp4 to fix this issue. It also corrects a problem that you found with checking enabled. >> --- /dev/null >> +++ b/gcc/testsuite/gfortran.dg/goacc/derived-types.f90 >> @@ -0,0 +1,78 @@ >> +! Test ACC UPDATE with derived types. The DEVICE clause depends on an >> +! accelerator being present. > > I guess that "DEVICE" comment here is a leftover? (Doesn't apply to a > compile test.) > >> +module dt >> + integer, parameter :: n = 10 >> + type inner >> + integer :: d(n) >> + end type inner >> + type dtype >> + integer(8) :: a, b, c(n) >> + type(inner) :: in >> + end type dtype >> +end module dt >> + >> +program derived_acc >> + use dt >> + >> + implicit none >> + type(dtype):: var >> + integer i >> + !$acc declare create(var) >> + !$acc declare pcopy(var%a) ! { dg-error "Syntax error in OpenMP" } >> + >> + !$acc update host(var) >> + !$acc update host(var%a) >> + !$acc update device(var) >> + !$acc update device(var%a) >> +[...] > >> --- /dev/null >> +++ b/libgomp/testsuite/libgomp.oacc-fortran/update-2.f90 >> @@ -0,0 +1,285 @@ >> +! Test ACC UPDATE with derived types. The DEVICE clause depends on an >> +! accelerator being present. > > Why? Shouldn "!$acc update device" just be a no-op for host execution? Just more test coverage. Cesar 2017-02-01 Cesar Philippidis gcc/fortran/ * openmp.c (gfc_match_omp_variable_list): Eliminate a warning when checking for derived types. * trans-openmp.c (gfc_trans_omp_clauses_1): Don't cast derived type pointers to void pointers. diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index 2782a8d..b3506d4 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -243,8 +243,8 @@ gfc_match_omp_variable_list (const char *str, gfc_omp_namelist **list, case MATCH_YES: gfc_expr *expr; expr = NULL; - if (allow_sections && gfc_peek_ascii_char () == '(' - || allow_derived && gfc_peek_ascii_char () == '%') + if ((allow_sections && gfc_peek_ascii_char () == '(') + || (allow_derived && gfc_peek_ascii_char () == '%')) { gfc_current_locus = cur_loc; m = gfc_match_variable (, 0); diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 7826e1c..80aa421 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -1986,9 +1986,10 @@ gfc_trans_omp_clauses_1 (stmtblock_t *block, gfc_omp_clauses *clauses, TREE_TYPE (field), decl, field, NULL_TREE); type = TREE_TYPE (scratch); - ptr =
Re: [gomp4] add support for derived types in ACC UPDATE
Hi Cesar! On Thu, 10 Nov 2016 09:38:33 -0800, Cesar Philippidiswrote: > This patch has been committed to gomp-4_0-branch. > --- a/gcc/fortran/openmp.c > +++ b/gcc/fortran/openmp.c > @@ -242,7 +243,8 @@ gfc_match_omp_variable_list (const char *str, > gfc_omp_namelist **list, > case MATCH_YES: > gfc_expr *expr; > expr = NULL; > - if (allow_sections && gfc_peek_ascii_char () == '(') > + if (allow_sections && gfc_peek_ascii_char () == '(' > + || allow_derived && gfc_peek_ascii_char () == '%') > { > gfc_current_locus = cur_loc; > m = gfc_match_variable (, 0); [...]/source-gcc/gcc/fortran/openmp.c: In function 'match {+gfc_match_omp_variable_list(const char*, gfc_omp_namelist**, bool, bool*, gfc_omp_namelist***, bool, bool)':+} [...]/source-gcc/gcc/fortran/openmp.c:246:23: warning: suggest parentheses around '&&' within '||' [-Wparentheses] if (allow_sections && gfc_peek_ascii_char () == '(' ^ > --- a/gcc/fortran/trans-openmp.c > +++ b/gcc/fortran/trans-openmp.c > @@ -1938,7 +1938,66 @@ gfc_trans_omp_clauses_1 (stmtblock_t *block, > gfc_omp_clauses *clauses, > tree decl = gfc_get_symbol_decl (n->sym); > if (DECL_P (decl)) > TREE_ADDRESSABLE (decl) = 1; > - if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL) > + /* Handle derived-typed members for OpenACC Update. */ > + if (n->sym->ts.type == BT_DERIVED > + && n->expr != NULL && n->expr->ref != NULL > + && (n->expr->ref->next == NULL > + || (n->expr->ref->next != NULL > + && n->expr->ref->next->type == REF_ARRAY > + && n->expr->ref->next->u.ar.type == AR_FULL))) > + { > + gfc_ref *ref = n->expr->ref; > + tree orig_decl = decl; [...]/source-gcc/gcc/fortran/trans-openmp.c: In function 'tree_node* gfc_trans_omp_clauses_1(stmtblock_t*, gfc_omp_clauses*, locus, bool)': [...]/source-gcc/gcc/fortran/trans-openmp.c:1947:10: warning: unused variable 'orig_decl' [-Wunused-variable] tree orig_decl = decl; ^ > --- /dev/null > +++ b/gcc/testsuite/gfortran.dg/goacc/derived-types.f90 > @@ -0,0 +1,78 @@ > +! Test ACC UPDATE with derived types. The DEVICE clause depends on an > +! accelerator being present. I guess that "DEVICE" comment here is a leftover? (Doesn't apply to a compile test.) > +module dt > + integer, parameter :: n = 10 > + type inner > + integer :: d(n) > + end type inner > + type dtype > + integer(8) :: a, b, c(n) > + type(inner) :: in > + end type dtype > +end module dt > + > +program derived_acc > + use dt > + > + implicit none > + type(dtype):: var > + integer i > + !$acc declare create(var) > + !$acc declare pcopy(var%a) ! { dg-error "Syntax error in OpenMP" } > + > + !$acc update host(var) > + !$acc update host(var%a) > + !$acc update device(var) > + !$acc update device(var%a) > +[...] > --- /dev/null > +++ b/libgomp/testsuite/libgomp.oacc-fortran/update-2.f90 > @@ -0,0 +1,285 @@ > +! Test ACC UPDATE with derived types. The DEVICE clause depends on an > +! accelerator being present. Why? Shouldn "!$acc update device" just be a no-op for host execution? Grüße Thomas > +! { dg-do run { target openacc_nvidia_accel_selected } } > + > +module dt > + integer, parameter :: n = 10 > + type inner > + integer :: d(n) > + end type inner > + type mytype > + integer(8) :: a, b, c(n) > + type(inner) :: in > + end type mytype > +end module dt > + > +program derived_acc > + use dt > + > + implicit none > + integer i, res > + type(mytype) :: var > + > + var%a = 0 > + var%b = 1 > + var%c(:) = 10 > + var%in%d(:) = 100 > + > + var%c(:) = 10 > + > + !$acc enter data copyin(var) > + > + !$acc parallel loop present(var) > + do i = 1, 1 > + var%a = var%b > + end do > + !$acc end parallel loop > + > + !$acc update host(var%a) > + > + if (var%a /= var%b) call abort > + > + var%b = 100 > + > + !$acc update device(var%b) > + > + !$acc parallel loop present(var) > + do i = 1, 1 > + var%a = var%b > + end do > + !$acc end parallel loop > + > + !$acc update host(var%a) > + > + if (var%a /= var%b) call abort > + > + !$acc parallel loop present (var) > + do i = 1, n > + var%c(i) = i > + end do > + !$acc end parallel loop > + > + !$acc update host(var%c) > + > + var%a = -1 > + > + do i = 1, n > + if (var%c(i) /= i) call abort > + var%c(i) = var%a > + end do > + > + !$acc update device(var%a) > + !$acc update device(var%c) > + > + res = 0 > + > + !$acc parallel loop present(var) reduction(+:res) > + do i = 1, n > + if (var%c(i) /= var%a) res = res + 1 > + end do > + > + if (res /= 0) call abort > + > + var%c(:) = 0 > + > + !$acc update device(var%c) > + > + !$acc parallel loop
[gomp4] add support for derived types in ACC UPDATE
OpenACC 2.0a has limited support for fortran derived types. Basically, derived type variables are only supported in ACC UPDATE. Rather than adding generalized support for derived times in the gimplifier, this patch has the fortran FE pass both subarrays and arrays as void pointers with an appropriate OMP_CLAUSE_SIZE. ACC UPDATE is an executable directive, and the gimplifier would just end up pruning out all of the unnecessary supporting data clauses otherwise. As of right now, GCC still lacks support for non-contiguous subarray arguments to ACC UPDATE. I'm not sure why it was decided to let ACC UPDATE support non-contiguous subarrays, but it already is an oddball with its lone support for derived types. This patch has been committed to gomp-4_0-branch. Cesar 2016-11-10 Cesar Philippidisgcc/fortran/ * openmp.c (gfc_match_omp_variable_list): New allow_derived argument. (gfc_match_omp_map_clause): Update call to gfc_match_omp_variable_list. (gfc_match_omp_clauses): Update calls to gfc_match_omp_map_clause. (gfc_match_oacc_update): Update call to gfc_match_omp_clauses. (resolve_omp_clauses): Permit derived type variables in ACC UPDATE clauses. * trans-openmp.c (gfc_trans_omp_clauses_1): Lower derived type members. gcc/ * gimplify.c (gimplify_scan_omp_clauses): Update handling of ACC UPDATE variables. gcc/testsuite/ * gfortran.dg/goacc/derived-types.f90: New test. libgomp/ * testsuite/libgomp.oacc-fortran/update-2.f90: New test. diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index 95885bc..0a9d137 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -216,7 +216,8 @@ static match gfc_match_omp_variable_list (const char *str, gfc_omp_namelist **list, bool allow_common, bool *end_colon = NULL, gfc_omp_namelist ***headp = NULL, - bool allow_sections = false) + bool allow_sections = false, + bool allow_derived = false) { gfc_omp_namelist *head, *tail, *p; locus old_loc, cur_loc; @@ -242,7 +243,8 @@ gfc_match_omp_variable_list (const char *str, gfc_omp_namelist **list, case MATCH_YES: gfc_expr *expr; expr = NULL; - if (allow_sections && gfc_peek_ascii_char () == '(') + if (allow_sections && gfc_peek_ascii_char () == '(' + || allow_derived && gfc_peek_ascii_char () == '%') { gfc_current_locus = cur_loc; m = gfc_match_variable (, 0); @@ -634,10 +636,11 @@ cleanup: static bool gfc_match_omp_map_clause (gfc_omp_namelist **list, gfc_omp_map_op map_op, - bool common_blocks) + bool common_blocks, bool allow_derived) { gfc_omp_namelist **head = NULL; - if (gfc_match_omp_variable_list ("", list, common_blocks, NULL, , true) + if (gfc_match_omp_variable_list ("", list, common_blocks, NULL, , true, + allow_derived) == MATCH_YES) { gfc_omp_namelist *n; @@ -655,7 +658,8 @@ gfc_match_omp_map_clause (gfc_omp_namelist **list, gfc_omp_map_op map_op, static match gfc_match_omp_clauses (gfc_omp_clauses **cp, uint64_t mask, uint64_t dtype_mask, bool first = true, - bool needs_space = true, bool openacc = false) + bool needs_space = true, bool openacc = false, + bool allow_derived = false) { gfc_omp_clauses *base_clauses, *c = gfc_get_omp_clauses (); locus old_loc; @@ -773,7 +777,8 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, uint64_t mask, if ((mask & OMP_CLAUSE_COPY) && gfc_match ("copy ( ") == MATCH_YES && gfc_match_omp_map_clause (>lists[OMP_LIST_MAP], - OMP_MAP_FORCE_TOFROM, openacc)) + OMP_MAP_FORCE_TOFROM, openacc, + allow_derived)) continue; if (mask & OMP_CLAUSE_COPYIN) { @@ -781,7 +786,8 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, uint64_t mask, { if (gfc_match ("copyin ( ") == MATCH_YES && gfc_match_omp_map_clause (>lists[OMP_LIST_MAP], - OMP_MAP_FORCE_TO, true)) + OMP_MAP_FORCE_TO, true, + allow_derived)) continue; } else if (gfc_match_omp_variable_list ("copyin (", @@ -792,7 +798,8 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, uint64_t mask, if ((mask & OMP_CLAUSE_COPYOUT) && gfc_match ("copyout ( ") == MATCH_YES && gfc_match_omp_map_clause (>lists[OMP_LIST_MAP], - OMP_MAP_FORCE_FROM, true)) + OMP_MAP_FORCE_FROM, true, + allow_derived)) continue; if ((mask & OMP_CLAUSE_COPYPRIVATE) && gfc_match_omp_variable_list ("copyprivate (", @@ -802,14 +809,15 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, uint64_t mask, if ((mask & OMP_CLAUSE_CREATE) && gfc_match ("create ( ") == MATCH_YES && gfc_match_omp_map_clause (>lists[OMP_LIST_MAP], - OMP_MAP_FORCE_ALLOC, true)) + OMP_MAP_FORCE_ALLOC, true, + allow_derived)) continue; break; case 'd': if ((mask & OMP_CLAUSE_DELETE) && gfc_match ("delete ( ") == MATCH_YES &&