public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Julian Brown <julian@codesourcery.com>
To: <gcc-patches@gcc.gnu.org>
Cc: Thomas Schwinge <thomas@codesourcery.com>,
	Jakub Jelinek	<jakub@redhat.com>,
	Tobias Burnus <tobias@codesourcery.com>,
	<Catherine_Moore@mentor.com>, <fortran@gcc.gnu.org>
Subject: [PATCH 13/13] Fortran polymorphic class-type support for OpenACC
Date: Wed, 18 Dec 2019 06:05:00 -0000	[thread overview]
Message-ID: <349a9c45db241c946bb17ea0a3b620308abc3a14.1576648001.git.julian@codesourcery.com> (raw)
In-Reply-To: <cover.1576648001.git.julian@codesourcery.com>

This patch builds on the Fortran front-end support posted earlier in
this series to enable polymorphic class pointers to be used in OpenACC
directives as well. It was last posted here:

  https://gcc.gnu.org/ml/gcc-patches/2019-10/msg00541.html

This version is largely the same as the previous posted version,
modulo rebasing.

Tested alongside other patches in this series with offloading to
NVPTX. OK?

Thanks,

Julian

ChangeLog

	gcc/fortran/
	* openmp.c (resolve_oacc_data_clauses): Don't disallow allocatable
	polymorphic types for OpenACC.
	* trans-openmp.c (gfc_trans_omp_clauses): Support polymorphic class
	types.

	libgomp/
	* testsuite/libgomp.oacc-fortran/class-ptr-param.f95: New test.
	* testsuite/libgomp.oacc-fortran/classtypes-1.f95: New test.
	* testsuite/libgomp.oacc-fortran/classtypes-2.f95: New test.
---
 gcc/fortran/openmp.c                          |   6 -
 gcc/fortran/trans-openmp.c                    |  69 +++++++++---
 .../libgomp.oacc-fortran/class-ptr-param.f95  |  34 ++++++
 .../libgomp.oacc-fortran/classtypes-1.f95     |  48 ++++++++
 .../libgomp.oacc-fortran/classtypes-2.f95     | 106 ++++++++++++++++++
 5 files changed, 244 insertions(+), 19 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/class-ptr-param.f95
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/classtypes-1.f95
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/classtypes-2.f95

diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index d79f4a90271..d1a6f2eddca 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -3922,12 +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)
 {
-  if ((sym->ts.type == BT_ASSUMED && sym->attr.allocatable)
-      || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
-	  && CLASS_DATA (sym)->attr.allocatable))
-    gfc_error ("ALLOCATABLE object %qs of polymorphic type "
-	       "in %s clause at %L", sym->name, name, &loc);
-  check_symbol_not_pointer (sym, loc, name);
   check_array_not_assumed (sym, loc, name);
 }
 
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index d091b6a6d62..7ef573479b3 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -2472,14 +2472,42 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 		  tree present = (gfc_omp_is_optional_argument (decl)
 				  ? gfc_omp_check_optional_argument (decl, true)
 				  : NULL_TREE);
-		  if (POINTER_TYPE_P (TREE_TYPE (decl))
-		      && (gfc_omp_privatize_by_reference (decl)
-			  || GFC_DECL_GET_SCALAR_POINTER (decl)
-			  || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
-			  || GFC_DECL_CRAY_POINTEE (decl)
-			  || GFC_DESCRIPTOR_TYPE_P
-					(TREE_TYPE (TREE_TYPE (decl)))
-			  || n->sym->ts.type == BT_DERIVED))
+		  if (n->sym->ts.type == BT_CLASS)
+		    {
+		      tree type = TREE_TYPE (decl);
+		      if (n->sym->attr.optional)
+			sorry ("optional class parameter");
+		      if (POINTER_TYPE_P (type))
+			{
+			  node4 = build_omp_clause (input_location,
+						    OMP_CLAUSE_MAP);
+			  OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER);
+			  OMP_CLAUSE_DECL (node4) = decl;
+			  OMP_CLAUSE_SIZE (node4) = size_int (0);
+			  decl = build_fold_indirect_ref (decl);
+			}
+		      tree ptr = gfc_class_data_get (decl);
+		      ptr = build_fold_indirect_ref (ptr);
+		      OMP_CLAUSE_DECL (node) = ptr;
+		      OMP_CLAUSE_SIZE (node) = gfc_class_vtab_size_get (decl);
+		      node2 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
+		      OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_TO_PSET);
+		      OMP_CLAUSE_DECL (node2) = decl;
+		      OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type);
+		      node3 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
+		      OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_ATTACH_DETACH);
+		      OMP_CLAUSE_DECL (node3) = gfc_class_data_get (decl);
+		      OMP_CLAUSE_SIZE (node3) = size_int (0);
+		      goto finalize_map_clause;
+		    }
+		  else if (POINTER_TYPE_P (TREE_TYPE (decl))
+			   && (gfc_omp_privatize_by_reference (decl)
+			       || GFC_DECL_GET_SCALAR_POINTER (decl)
+			       || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
+			       || GFC_DECL_CRAY_POINTEE (decl)
+			       || GFC_DESCRIPTOR_TYPE_P
+					     (TREE_TYPE (TREE_TYPE (decl)))
+			       || n->sym->ts.type == BT_DERIVED))
 		    {
 		      tree orig_decl = decl;
 		      node4 = build_omp_clause (input_location,
@@ -2646,11 +2674,15 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 
 		  symbol_attribute sym_attr;
 
-		  sym_attr = lastcomp->u.c.component->attr;
+		  if (lastcomp->u.c.component->ts.type == BT_CLASS)
+		    sym_attr = CLASS_DATA (lastcomp->u.c.component)->attr;
+		  else
+		    sym_attr = lastcomp->u.c.component->attr;
 
 		  gfc_init_se (&se, NULL);
 
 		  if (!sym_attr.dimension
+		      && lastcomp->u.c.component->ts.type != BT_CLASS
 		      && lastcomp->u.c.component->ts.type != BT_DERIVED)
 		    {
 		      /* Last component is a scalar.  */
@@ -2680,13 +2712,24 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 
 		  tree inner = se.expr;
 
-		  /* Last component is a derived type.  */
-		  if (lastcomp->u.c.component->ts.type == BT_DERIVED)
+		  /* Last component is a derived type or class pointer.  */
+		  if (lastcomp->u.c.component->ts.type == BT_DERIVED
+		      || lastcomp->u.c.component->ts.type == BT_CLASS)
 		    {
 		      if (sym_attr.allocatable || sym_attr.pointer)
 			{
-			  tree data = inner;
-			  tree size = TYPE_SIZE_UNIT (TREE_TYPE (inner));
+			  tree data, size;
+
+			  if (lastcomp->u.c.component->ts.type == BT_CLASS)
+			    {
+			      data = gfc_class_data_get (inner);
+			      size = gfc_class_vtab_size_get (inner);
+			    }
+			  else  /* BT_DERIVED.  */
+			    {
+			      data = inner;
+			      size = TYPE_SIZE_UNIT (TREE_TYPE (inner));
+			    }
 
 			  OMP_CLAUSE_DECL (node)
 			    = build_fold_indirect_ref (data);
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/class-ptr-param.f95 b/libgomp/testsuite/libgomp.oacc-fortran/class-ptr-param.f95
new file mode 100644
index 00000000000..80147337c9d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/class-ptr-param.f95
@@ -0,0 +1,34 @@
+! { dg-do run }
+
+module typemod
+
+type mytype
+  integer :: a
+end type mytype
+
+contains
+
+subroutine mysub(c)
+  implicit none
+
+  class(mytype), allocatable :: c
+
+!$acc parallel copy(c)
+  c%a = 5
+!$acc end parallel
+end subroutine mysub
+
+end module typemod
+
+program main
+  use typemod
+  implicit none
+
+  class(mytype), allocatable :: myvar
+  allocate(mytype :: myvar)
+
+  myvar%a = 0
+  call mysub(myvar)
+
+  if (myvar%a .ne. 5) stop 1
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/classtypes-1.f95 b/libgomp/testsuite/libgomp.oacc-fortran/classtypes-1.f95
new file mode 100644
index 00000000000..f16f42fc3af
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/classtypes-1.f95
@@ -0,0 +1,48 @@
+! { dg-do run }
+
+module typemod
+
+type :: typeimpl
+  real, pointer :: p(:) => null()
+end type typeimpl
+
+type :: basictype
+  class(typeimpl), pointer :: p => null()
+end type basictype
+
+type, extends(basictype) :: regulartype
+  character :: void
+end type regulartype
+
+end module typemod
+
+program main
+  use typemod
+  implicit none
+  type(regulartype), pointer :: myvar
+  integer :: i
+  real :: j, k
+
+  allocate(myvar)
+  allocate(myvar%p)
+  allocate(myvar%p%p(1:100))
+
+  do i=1,100
+    myvar%p%p(i) = -1.0
+  end do
+
+!$acc enter data copyin(myvar, myvar%p) create(myvar%p%p)
+
+!$acc parallel loop present(myvar%p%p)
+  do i=1,100
+    myvar%p%p(i) = i * 2
+  end do
+!$acc end parallel loop
+
+!$acc exit data copyout(myvar%p%p) delete(myvar, myvar%p)
+
+  do i=1,100
+    if (myvar%p%p(i) .ne. i * 2) stop 1
+  end do
+
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/classtypes-2.f95 b/libgomp/testsuite/libgomp.oacc-fortran/classtypes-2.f95
new file mode 100644
index 00000000000..ad80ec2a0ef
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/classtypes-2.f95
@@ -0,0 +1,106 @@
+! { dg-do run }
+
+module wrapper_mod
+
+type compute
+  integer, allocatable :: block(:,:)
+contains
+  procedure :: initialize
+end type compute
+
+type, extends(compute) :: cpu_compute
+  integer :: blocksize
+contains
+  procedure :: setblocksize
+end type cpu_compute
+
+type, extends(compute) :: gpu_compute
+  integer :: numgangs
+  integer :: numworkers
+  integer :: vectorsize
+  integer, allocatable :: gpu_block(:,:)
+contains
+  procedure :: setdims
+end type gpu_compute
+
+contains
+
+subroutine initialize(c, length, width)
+  implicit none
+  class(compute) :: c
+  integer :: length
+  integer :: width
+  integer :: i
+  integer :: j
+
+  allocate (c%block(length, width))
+
+  do i=1,length
+    do j=1, width
+      c%block(i,j) = i + j
+    end do
+  end do
+end subroutine initialize
+
+subroutine setdims(c, g, w, v)
+  implicit none
+  class(gpu_compute) :: c
+  integer :: g
+  integer :: w
+  integer :: v
+  c%numgangs = g
+  c%numworkers = w
+  c%vectorsize = v
+end subroutine setdims
+
+subroutine setblocksize(c, bs)
+  implicit none
+  class(cpu_compute) :: c
+  integer :: bs
+  c%blocksize = bs
+end subroutine setblocksize
+
+end module wrapper_mod
+
+program main
+  use wrapper_mod
+  implicit none
+  class(compute), allocatable, target :: mycomp
+  integer :: i, j
+
+  allocate(gpu_compute::mycomp)
+
+  call mycomp%initialize(1024,1024)
+
+  !$acc enter data copyin(mycomp)
+
+  select type (mycomp)
+  type is (cpu_compute)
+    call mycomp%setblocksize(32)
+  type is (gpu_compute)
+    call mycomp%setdims(32,32,32)
+    allocate(mycomp%gpu_block(1024,1024))
+    !$acc update device(mycomp)
+    !$acc parallel copyin(mycomp%block) copyout(mycomp%gpu_block)
+    !$acc loop gang worker vector collapse(2)
+    do i=1,1024
+      do j=1,1024
+        mycomp%gpu_block(i,j) = mycomp%block(i,j) + 1
+      end do
+    end do
+    !$acc end parallel
+  end select
+
+  !$acc exit data copyout(mycomp)
+
+  select type (g => mycomp)
+  type is (gpu_compute)
+  do i = 1, 1024
+    do j = 1, 1024
+      if (g%gpu_block(i,j) .ne. i + j + 1) stop 1
+    end do
+  end do
+  end select
+
+  deallocate(mycomp)
+end program main
-- 
2.23.0

  parent reply	other threads:[~2019-12-18  6:05 UTC|newest]

Thread overview: 81+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-10 17:11 [PATCH 0/3] OpenACC 2.6 manual deep copy support (attach/detach) Julian Brown
2018-11-10 17:11 ` [PATCH 1/3] Host-to-device transfer coalescing & magic offset value self-documentation Julian Brown
2018-12-21 10:56   ` libgomp/target.c magic constants self-documentation Thomas Schwinge
2019-05-29 14:48     ` Thomas Schwinge
2018-11-10 17:11 ` [PATCH 2/3] Factor out duplicate code in gimplify_scan_omp_clauses Julian Brown
2018-12-18 14:16   ` Julian Brown
2018-12-18 14:50   ` Jakub Jelinek
2018-11-10 17:12 ` [PATCH 3/3] OpenACC 2.6 manual deep copy support (attach/detach) Julian Brown
2018-11-11 17:04   ` Bernhard Reutner-Fischer
2018-11-30 11:41   ` [PATCH] " Julian Brown
2018-12-03 17:03     ` Julian Brown
2018-12-07 13:50     ` Jakub Jelinek
2018-12-10 19:42       ` Julian Brown
2018-12-13 10:57         ` Jakub Jelinek
2018-12-14 19:00           ` Julian Brown
2018-12-18 12:25             ` Jakub Jelinek
2018-12-22 13:37             ` Thomas Schwinge
2019-10-18 17:20         ` Thomas Schwinge
2019-11-06 18:44           ` Julian Brown
2019-11-22 23:54             ` Julian Brown
2019-11-25 10:53               ` Tobias Burnus
2019-11-26  2:54                 ` Julian Brown
2019-12-17 12:16                   ` Thomas Schwinge
2019-12-17 17:28                     ` [WIP] OpenACC 'acc_attach*', 'acc_detach*' runtime library routines (was: [PATCH] OpenACC 2.6 manual deep copy support (attach/detach)) Thomas Schwinge
2019-12-18  6:03                   ` [PATCH 00/13] OpenACC 2.6 manual deep copy support Julian Brown
2019-12-18  6:03                     ` [PATCH 02/13] OpenACC reference count overhaul Julian Brown
2020-05-19 15:42                       ` Thomas Schwinge
2020-06-04 18:13                         ` [OpenACC] Use 'tgt' returned from 'gomp_map_vars' (was: [PATCH 02/13] OpenACC reference count overhaul) Thomas Schwinge
2020-05-19 15:49                       ` [PATCH 02/13] OpenACC reference count overhaul Thomas Schwinge
2020-05-19 15:58                       ` Thomas Schwinge
2020-06-25 11:03                         ` Thomas Schwinge
2020-07-03 15:29                           ` Thomas Schwinge
2019-12-18  6:03                     ` [PATCH 03/13] OpenACC reference count consistency checking Julian Brown
2019-12-18  6:03                     ` [PATCH 01/13] Use aux struct in libgomp for infrequently-used/API-specific data Julian Brown
2019-12-18  6:04                     ` [PATCH 04/13] Use gomp_map_val for OpenACC host-to-device address translation Julian Brown
2019-12-18  6:04                     ` [PATCH 05/13] Factor out duplicate code in gimplify_scan_omp_clauses Julian Brown
2019-12-18  6:04                     ` [PATCH 09/13] OpenACC 2.6 deep copy: C and C++ front-end parts Julian Brown
2019-12-24  5:05                       ` Thomas Schwinge
2019-12-26 19:04                       ` Jason Merrill
2021-06-10 11:03                       ` Thomas Schwinge
2019-12-18  6:04                     ` [PATCH 06/13] OpenACC 2.6 deep copy: attach/detach API routines Julian Brown
2019-12-18  6:04                     ` [PATCH 08/13] OpenACC 2.6 deep copy: middle-end parts Julian Brown
2019-12-21 21:51                       ` Thomas Schwinge
2019-12-18  6:05                     ` [PATCH 12/13] OpenACC 2.6 deep copy: Fortran execution tests Julian Brown
2019-12-18  6:05                     ` [PATCH 07/13] OpenACC 2.6 deep copy: libgomp parts Julian Brown
2019-12-21 23:37                       ` Thomas Schwinge
2020-01-03 12:26                         ` Julian Brown
2020-05-20  9:37                       ` Thomas Schwinge
2020-06-05 16:23                         ` [OpenACC 'exit data'] Simplify 'GOMP_MAP_STRUCT' handling (was: [PATCH 07/13] OpenACC 2.6 deep copy: libgomp parts) Thomas Schwinge
2020-06-05 16:36                         ` [OpenACC 'exit data'] Strip 'GOMP_MAP_STRUCT' mappings " Thomas Schwinge
2020-05-20 14:52                       ` [PATCH 07/13] OpenACC 2.6 deep copy: libgomp parts Thomas Schwinge
2020-05-20 19:11                         ` Julian Brown
2020-06-04 18:35                           ` [OpenACC] Repair/restore 'is_tgt_unmapped' checking (was: [PATCH 07/13] OpenACC 2.6 deep copy: libgomp parts) Thomas Schwinge
2020-06-04 18:53                       ` [PATCH 07/13] OpenACC 2.6 deep copy: libgomp parts Thomas Schwinge
2020-06-05 10:39                       ` Thomas Schwinge
2020-06-05 20:28                         ` Julian Brown
2020-06-05 11:17                       ` Thomas Schwinge
2020-06-05 20:31                         ` Julian Brown
2020-06-09 10:41                           ` OpenACC 'attach'/'detach' has no business affecting user-visible reference counting (was: [PATCH 07/13] OpenACC 2.6 deep copy: libgomp parts) Thomas Schwinge
2020-06-09 12:23                             ` Julian Brown
2020-06-18 18:21                             ` Julian Brown
2020-07-16  8:35                               ` OpenACC 'attach'/'detach' has no business affecting user-visible reference counting Thomas Schwinge
2020-06-26  9:20                       ` [PATCH 07/13] OpenACC 2.6 deep copy: libgomp parts Thomas Schwinge
2020-07-16  9:35                         ` Thomas Schwinge
2020-07-16 21:21                           ` Julian Brown
2020-07-17  9:12                             ` Thomas Schwinge
2020-06-30 15:58                       ` Thomas Schwinge
2019-12-18  6:05                     ` Julian Brown [this message]
2019-12-18  6:05                     ` [PATCH 11/13] OpenACC 2.6 deep copy: C and C++ execution tests Julian Brown
2020-06-04 18:43                       ` Fix 'sizeof' usage in 'libgomp.oacc-c-c++-common/deep-copy-{7, 8}.c' (was: [PATCH 11/13] OpenACC 2.6 deep copy: C and C++ execution tests) Thomas Schwinge
2023-10-31 14:00                       ` Add OpenACC 'acc_map_data' variant to 'libgomp.oacc-c-c++-common/deep-copy-8.c' " Thomas Schwinge
2019-12-18  7:20                     ` [PATCH 10/13] OpenACC 2.6 deep copy: Fortran front-end parts Julian Brown
2019-12-18 23:30                       ` Tobias Burnus
2019-12-20 12:25                         ` [committed] Improve is-coindexed check for OpenACC/OpenMP (was: [PATCH 10/13] OpenACC 2.6 deep copy: Fortran front-end parts) Tobias Burnus
2019-12-20 13:25                         ` [PATCH 10/13] OpenACC 2.6 deep copy: Fortran front-end parts Tobias Burnus
2019-12-20 10:08                       ` [patch,committed] Fix testsuite-fallout of OpenACC deep-copy patch (was: [PATCH 10/13] OpenACC 2.6 deep copy: Fortran front-end parts) Tobias Burnus
2019-12-18 18:24                     ` [PATCH 00/13] OpenACC 2.6 manual deep copy support Thomas Schwinge
2019-12-20  1:21                       ` Julian Brown
2019-12-20 14:36                     ` OpenACC regression and development pace Thomas Koenig
2020-06-04 18:07                     ` [OpenACC] XFAIL behavior of over-eager 'finalize' clause (was: [PATCH 00/13] OpenACC 2.6 manual deep copy support) Thomas Schwinge
2019-12-17 16:53             ` In 'libgomp/target.c', 'struct splay_tree_key_s', use 'struct splay_tree_aux' for infrequently-used or API-specific data (was: [PATCH] OpenACC 2.6 manual deep copy support (attach/detach)) Thomas Schwinge

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=349a9c45db241c946bb17ea0a3b620308abc3a14.1576648001.git.julian@codesourcery.com \
    --to=julian@codesourcery.com \
    --cc=Catherine_Moore@mentor.com \
    --cc=fortran@gcc.gnu.org \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=thomas@codesourcery.com \
    --cc=tobias@codesourcery.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).