From 9a4d32f85ccebc0ee4b24e6d9d7a4f11c04d7146 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 2 Feb 2021 03:44:34 -0800 Subject: [PATCH] openacc: Allow strided arrays in update directives OpenACC 3.0 ("2.14.4. Update Directive") states: Noncontiguous subarrays may appear. It is implementation-specific whether noncontiguous regions are updated by using one transfer for each contiguous subregion, or whether the non-contiguous data is packed, transferred once, and unpacked, or whether one or more larger subarrays (no larger than the smallest contiguous region that contains the specified subarray) are updated. This patch relaxes some conditions in the Fortran front-end so that strided accesses are permitted for update directives. gcc/fortran/ * openmp.c (resolve_omp_clauses): Omit OpenACC update in contiguity check and stride-specified error. gcc/testsuite/ * gfortran.dg/goacc/array-with-dt-2.f90: New test. libgomp/ * testsuite/libgomp.oacc-fortran/array-stride-dt-1.f90: New test. --- gcc/fortran/openmp.c | 5 ++- .../gfortran.dg/goacc/array-with-dt-2.f90 | 10 +++++ .../libgomp.oacc-fortran/array-stride-dt-1.f90 | 44 ++++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/goacc/array-with-dt-2.f90 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/array-stride-dt-1.f90 diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index aab17f0..797f6c8 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -5192,7 +5192,8 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, array isn't contiguous. An expression such as arr(-n:n,-n:n) could be contiguous even if it looks like it may not be. */ - if (list != OMP_LIST_CACHE + if (code->op != EXEC_OACC_UPDATE + && list != OMP_LIST_CACHE && list != OMP_LIST_DEPEND && !gfc_is_simply_contiguous (n->expr, false, true) && gfc_is_not_contiguous (n->expr)) @@ -5230,7 +5231,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, int i; gfc_array_ref *ar = &array_ref->u.ar; for (i = 0; i < ar->dimen; i++) - if (ar->stride[i]) + if (ar->stride[i] && code->op != EXEC_OACC_UPDATE) { gfc_error ("Stride should not be specified for " "array section in %s clause at %L", diff --git a/gcc/testsuite/gfortran.dg/goacc/array-with-dt-2.f90 b/gcc/testsuite/gfortran.dg/goacc/array-with-dt-2.f90 new file mode 100644 index 0000000..807580d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/array-with-dt-2.f90 @@ -0,0 +1,10 @@ +type t + integer, allocatable :: A(:,:) +end type t + +type(t), allocatable :: b(:) + +!$acc update host(b(::2)) +!$acc update host(b(1)%A(::3,::4)) +end + diff --git a/libgomp/testsuite/libgomp.oacc-fortran/array-stride-dt-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/array-stride-dt-1.f90 new file mode 100644 index 0000000..f04d76d --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/array-stride-dt-1.f90 @@ -0,0 +1,44 @@ +! { dg-do run } + +type t + integer, allocatable :: A(:,:) +end type t + +type(t), allocatable :: b(:) + +integer :: i + +allocate(b(1:20)) +do i=1,20 + allocate(b(i)%A(1:20,1:20)) +end do + +do i=1,20 + b(i)%A(:,:) = 0 +end do + +!$acc enter data copyin(b) +do i=1,20 + !$acc enter data copyin(b(i)%A) +end do + +b(1)%A(:,:) = 5 + +!$acc update device(b(::2)) +!$acc update device(b(1)%A(::3,::4)) + +do i=1,20 + !$acc exit data copyout(b(i)%A) +end do +!$acc exit data copyout(b) + +! This is necessarily conservative because the "update" is allowed to copy +! e.g. the whole of the containing block for a discontinuous update. +! Try to ensure that the update covers a sufficient portion of the array. + +if (any(b(1)%A(::3,::4) .ne. 5)) stop 1 +do i=2,20 + if (any(b(i)%A(:,:) .ne. 0)) stop 2 +end do + +end -- 2.7.4