[PATCH 10/13] OpenACC 2.6 deep copy: Fortran front-end parts
Tobias Burnus
tobias@codesourcery.com
Wed Dec 18 22:51:00 GMT 2019
On 12/18/19 7:04 AM, Julian Brown wrote:
> This part contains the Fortran front-end support for parsing the new
> attach and detach clauses, as well as derived-type members on other
> data-movement clauses (copyin, copyout, etc.).
I browsed the patch and it looks mostly fine to me. However, I do have
comments related to the array refs.
> @@ -3890,9 +3922,6 @@ check_array_not_assumed (gfc_symbol *sym, locus loc, const char *name)
> static void
> resolve_oacc_data_clauses (gfc_symbol *sym, locus loc, const char *name)
> {
> + /* Disallow duplicate bare variable references and multiple
> + subarrays of the same array here, but allow multiple components of
> + the same (e.g. derived-type) variable. For the latter, duplicate
> + components are detected elsewhere. */
Do we have a test case for "the latter"?
> @@ -4470,23 +4514,43 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
> + gfc_ref *array_ref = NULL;
> + bool resolved = false;
> if (n->expr)
> {
> - if (!gfc_resolve_expr (n->expr)
> + array_ref = n->expr->ref;
> + resolved = gfc_resolve_expr (n->expr);
> +
> + /* Look through component refs to find last array
> + reference. */
> + if (openacc)
> + while (resolved
I would move the "resolved" into the "if" condition as it doesn't change
in the while loop.
> + && array_ref
> + && (array_ref->type == REF_COMPONENT
> + || (array_ref->type == REF_ARRAY
> + && array_ref->next
> + && (array_ref->next->type
> + == REF_COMPONENT))))
> + array_ref = array_ref->next;
> + }
> + if (array_ref
> + || (n->expr
> + && (!resolved || n->expr->expr_type != EXPR_VARIABLE)))
> + {
> + if (!resolved
> || n->expr->expr_type != EXPR_VARIABLE
> - || n->expr->ref == NULL
> - || n->expr->ref->next
> - || n->expr->ref->type != REF_ARRAY)
> + || array_ref->next
> + || array_ref->type != REF_ARRAY)
> gfc_error ("%qs in %s clause at %L is not a proper "
> "array section", n->sym->name, name,
> &n->where);
> - else if (n->expr->ref->u.ar.codimen)
> + else if (array_ref->u.ar.codimen)
> gfc_error ("Coarrays not supported in %s clause at %L",
> name, &n->where);
First, I believe the error message is wrong â coarrays are permitted but
only if their local data is accessed; this check checks whether a
coindex is present, i.e. whether the variable is accessed on a remote
process ("image"). Hence, the error should use something like "Entry
shall not be coindexed in %s clause at %L" or something like that.
Secondly, a coarray can exist at different places, e.g.
type t
integer :: i
end type t
type t2
integer, allocatable :: i[:]
type(t), allocatable :: x[:]
end type t2
type(t), allocatable :: A[:], B[:]
type(t) :: D[*]
type(t2) :: C
!$acc data copy(D[2]%i, A[4], B[4]%i, C%i[2], C%x[4]%i)
Here, C is not a coarray. But all those list items in the clause are
coindexed â but your new check will only detect those where the ultimate
component is coindexed. The quickest check for this is "gfc_is_coindexed (expr)".
Thirdly, I am not sure whether the following will work with your code:
type t
integer :: i(5), j(17), k
end type t
type(t) :: x(10)
!$acc data copy (x(:)%k, x(:)%j(3))
This data is strided; I don't quickly see whether that's rejected. (I also
didn't check whether it is valid, but I think it is not.)
> +/* Transparently dereference VAR if it is a pointer, reference, etc.
> + according to Fortran semantics. */
> +
> +tree
> +gfc_auto_dereference_var (gfc_symbol *sym, tree var, bool descriptor_only_p,
> + bool is_classarray)
I have to admit that 'transparently deference' and 'auto' puzzles me,
naming/description wise, but I don't have a good solution; but I like
the 'Dereference the expression, where needed' more
> + /* Dereference the expression, where needed. */
> + se->expr = gfc_auto_dereference_var (sym, se->expr, se->descriptor_only,
> + is_classarray);
> +++ b/gcc/fortran/trans-openmp.c
> + if (element)
> + {
> + gfc_conv_expr_reference (&se, n->expr);
> + gfc_add_block_to_block (block, &se.pre);
> + ptr = se.expr;
> + OMP_CLAUSE_SIZE (node)
> + = TYPE_SIZE_UNIT (TREE_TYPE (ptr));
This fits nicely on a single line; I think the ';' is in column 64!
Cheers,
Tobias
More information about the Fortran
mailing list