Make OpenACC 'acc_get_property' with 'acc_device_current' work (was: [PATCH] Add OpenACC 2.6 `acc_get_property' support)

Message ID 877e19lz2d.fsf@euler.schwinge.homeip.net
State New
Headers show
Series
  • Make OpenACC 'acc_get_property' with 'acc_device_current' work (was: [PATCH] Add OpenACC 2.6 `acc_get_property' support)
Related show

Commit Message

Thomas Schwinge Jan. 30, 2020, 3:54 p.m.
Hi!

On 2020-01-10T23:52:11+0100, I wrote:
> On 2019-12-21T23:02:38+0100, I wrote:

>> On 2019-12-20T17:46:57+0100, "Harwath, Frederik" <frederik@codesourcery.com> wrote:

>>>> > --- a/include/gomp-constants.h

>>>> > +++ b/include/gomp-constants.h

>

>>>> > +#define GOMP_DEVICE_CURRENT		-3

>

>>>> Should this actually get value '-1' instead of '-3'?  Or, is the OpenACC

>>>> 'acc_device_t' code already paying special attention to negative values

>>>> '-1', '-2'?  (I don't think so.)

>

>>>> | Also, 'acc_device_current' is a libgomp-internal thing (doesn't interface

>>>> | with the compiler proper), so strictly speaking 'GOMP_DEVICE_CURRENT'

>>>> | isn't needed in 'include/gomp-constants.h'.  But probably still a good

>>>> | idea to list it there, in this canonical place, to keep the several lists

>>>> | of device types coherent.

>

>>>> I still wonder about that...  ;-)

>

>> I still think that 'GOMP_DEVICE_CURENT' should get value '-1' (and

>> probably be rename 'GOACC_DEVICE_CURRENT' to make more obvious that it's

>> not related to the 'GOMP_DEVICE_*' ones), but we shall have a look at

>> that later (before GCC 10 release); that's libgomp/OpenACC-internal,

>> doesn't affect anything else.

>

> That's still pending.  Recently,

> <https://github.com/OpenACC/openacc-spec/issues/256> "Missing definition

> for acc_device_current" got filed; let's (also/first) watch/wait what

> comes out of that.


(That's still pending, but) notwithstanding the specific value we'll use
eventually, the 'acc_device_current' interface should work already now.

..., but I noticed that we don't have any test cases for that (so by that
definition, it must be broken).  The curious guy that I am sometimes ;-)
I gave that a try, and... "of course"... it doesn't work.  Please review
the attached (Tobias the Fortran test cases, please), and test with AMD
GCN offloading.  If approving this patch, please respond with
"Reviewed-by: NAME <EMAIL>" so that your effort will be recorded in the
commit log, see <https://gcc.gnu.org/wiki/Reviewed-by>.


Grüße
 Thomas

Comments

Frederik Harwath Feb. 3, 2020, 12:16 p.m. | #1
Hi Thomas,

On 30.01.20 16:54, Thomas Schwinge wrote:
> 

> [...] the 'acc_device_current' interface should work already now.

> 

> [...] Please review

> the attached (Tobias the Fortran test cases, please), and test with AMD

> GCN offloading.  If approving this patch, please respond with


I have tested the patch with AMD GCN offloading and I have observed no regressions.
The new tests pass as expected and print the correct output.
Great that you have extended the Fortran tests!

> diff --git a/libgomp/oacc-init.c b/libgomp/oacc-init.c

> index ef12b4c16d01..c28c0f689ba2 100644

> --- a/libgomp/oacc-init.c

> +++ b/libgomp/oacc-init.c

> @@ -796,7 +796,9 @@ get_property_any (int ord, acc_device_t d, acc_device_property_t prop)

> size_t

> acc_get_property (int ord, acc_device_t d, acc_device_property_t prop)

> {

> -  if (!known_device_type_p (d))

> +  if (d == acc_device_current)

> +    ; /* Allowed only for 'acc_get_property', 'acc_get_property_string'.  */

> +  else if (!known_device_type_p (d))

>     unknown_device_type_error(d);


I don't like the empty if branch very much. Introducing a variable
(for instance, "bool allowed_device_type = acc_device_current
|| known_device_type(d);") would also provide a place for your comment.
You could also extract a function to avoid duplicating the explanation
in acc_get_property_string.

The patch looks good to me.

Reviewed-by: Frederik Harwath  <frederik@codesourcery.com>


Best regards,
Frederik
Tobias Burnus Feb. 3, 2020, 2:41 p.m. | #2
Hi Thomas,

On 1/30/20 4:54 PM, Thomas Schwinge wrote:

>> That's still pending.  Recently,<https://github.com/OpenACC/openacc-spec/issues/256>  "Missing definition

>> for acc_device_current" got filed; let's (also/first) watch/wait what

>> comes out of that.


(Still pending.)

> Please review the attached (Tobias the Fortran test cases, please),

> and test with AMD GCN offloading.  If approving this patch, please respond with

> "Reviewed-by: NAME <EMAIL>" so that your effort will be recorded in the

> commit log, see<https://gcc.gnu.org/wiki/Reviewed-by>.


LGTM with the minor nit regarding the integer kind used
for dev_type (default/unspecified vs. "acc_device_kind").
To make you happy:

Reviewed-by: Tobias Burnus <tobias@codesourcery.com>


Thanks,

Tobias

> --- a/libgomp/openacc.f90

> +++ b/libgomp/openacc.f90

> @@ -766,6 +766,7 @@ module openacc

>   

>     ! From openacc_kinds

>     public :: acc_device_kind

> +  public :: acc_device_current


Good catch!

> +++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_get_property-aux.f90

> …

> +  subroutine expect_device_memory_properties (dev_type, dev_num, &

> +       expected_total_memory)

> +    integer, intent(in) :: dev_type


I think you should use (w/ or w/o "value" attribute)
    integer (acc_device_kind) :: dev_type
instead for consistency. It does not matter in practice but is nicer.

> +       expected_vendor, expected_name, expected_driver)

> +    integer, intent(in) :: dev_type

> +    integer, intent(in) :: dev_num

> +    character*(*), intent(in) :: expected_vendor


Likewise for dev_num.

(Side note: I personally prefer "character(*)" or (even better:) "character(len=*)"
to the "character*…" syntax – as I find it more readable. But that your syntax is
not even marked as obsolescent and, hence, is perfectly valid.)

> +    integer, intent(in) :: dev_num


Ditto.

Patch

From 5ce3725cf160f086e99c01e73c26a0bf5654f5b6 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <thomas@codesourcery.com>
Date: Wed, 29 Jan 2020 22:11:15 +0100
Subject: [PATCH] Make OpenACC 'acc_get_property' with 'acc_device_current'
 work

	libgomp/
	* oacc-init.c (acc_get_property, acc_get_property_string): Allow
	'acc_device_current'.
	* openacc.f90 (module openacc): Export 'acc_device_current'.
	* testsuite/libgomp.oacc-c-c++-common/acc_get_property-aux.c
	(expect_device_memory): Rename to...
	(expect_device_memory_properties): ... this.  Make 'static'.
	(expect_device_string_properties): Rename to...
	(expect_device_non_memory_properties): ... this.  Adjust all
	users.
	* testsuite/libgomp.oacc-c-c++-common/acc_get_property-aux.h: New
	file.
	* testsuite/libgomp.oacc-c-c++-common/acc_get_property-aux.c: Use it.
	* testsuite/libgomp.oacc-c-c++-common/acc_get_property-gcn.c:
	Likewise.
	* testsuite/libgomp.oacc-c-c++-common/acc_get_property-host.c:
	Likewise.
	* testsuite/libgomp.oacc-c-c++-common/acc_get_property-nvptx.c:
	Likewise.
	* testsuite/libgomp.oacc-c-c++-common/acc_get_property-gcn.c: Add
	some more testing.
	* testsuite/libgomp.oacc-c-c++-common/acc_get_property-host.c:
	Likewise.
	* testsuite/libgomp.oacc-c-c++-common/acc_get_property-nvptx.c:
	Likewise.
	* testsuite/libgomp.oacc-c-c++-common/acc_get_property.c:
	Likewise.
	* testsuite/libgomp.oacc-fortran/acc_get_property.f90: Likewise.
	* testsuite/libgomp.oacc-fortran/acc_get_property-aux.f90: New
	file.
	* testsuite/libgomp.oacc-fortran/acc_get_property-host.F90: New
	file.
---
 libgomp/oacc-init.c                           |   8 +-
 libgomp/openacc.f90                           |   1 +
 .../acc_get_property-aux.c                    |  76 ++++++-------
 .../acc_get_property-aux.h                    |  14 +++
 .../acc_get_property-gcn.c                    |  26 +++--
 .../acc_get_property-host.c                   |  26 +++--
 .../acc_get_property-nvptx.c                  |  27 +++--
 .../acc_get_property.c                        |  16 ++-
 .../acc_get_property-aux.f90                  | 102 ++++++++++++++++++
 .../acc_get_property-host.F90                 |  31 ++++++
 .../libgomp.oacc-fortran/acc_get_property.f90 |  15 ++-
 11 files changed, 274 insertions(+), 68 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-aux.h
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/acc_get_property-aux.f90
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/acc_get_property-host.F90

diff --git a/libgomp/oacc-init.c b/libgomp/oacc-init.c
index ef12b4c16d01..c28c0f689ba2 100644
--- a/libgomp/oacc-init.c
+++ b/libgomp/oacc-init.c
@@ -796,7 +796,9 @@  get_property_any (int ord, acc_device_t d, acc_device_property_t prop)
 size_t
 acc_get_property (int ord, acc_device_t d, acc_device_property_t prop)
 {
-  if (!known_device_type_p (d))
+  if (d == acc_device_current)
+    ; /* Allowed only for 'acc_get_property', 'acc_get_property_string'.  */
+  else if (!known_device_type_p (d))
     unknown_device_type_error(d);
 
   if (prop & GOACC_PROPERTY_STRING_MASK)
@@ -810,7 +812,9 @@  ialias (acc_get_property)
 const char *
 acc_get_property_string (int ord, acc_device_t d, acc_device_property_t prop)
 {
-  if (!known_device_type_p (d))
+  if (d == acc_device_current)
+    ; /* Allowed only for 'acc_get_property', 'acc_get_property_string'.  */
+  else if (!known_device_type_p (d))
     unknown_device_type_error(d);
 
   if (prop & GOACC_PROPERTY_STRING_MASK)
diff --git a/libgomp/openacc.f90 b/libgomp/openacc.f90
index e2639bf622ed..5112a4ee951a 100644
--- a/libgomp/openacc.f90
+++ b/libgomp/openacc.f90
@@ -766,6 +766,7 @@  module openacc
 
   ! From openacc_kinds
   public :: acc_device_kind
+  public :: acc_device_current
   public :: acc_device_none, acc_device_default, acc_device_host
   public :: acc_device_not_host, acc_device_nvidia, acc_device_radeon
 
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-aux.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-aux.c
index 47285fc7e63b..189fe1e26957 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-aux.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-aux.c
@@ -1,17 +1,44 @@ 
 /* Auxiliary functions for acc_get_property tests */
 /* { dg-do compile  { target skip-all-targets } } */
+/* See also '../libgomp.oacc-fortran/acc_get_property-aux.f90'.  */
 
 #include <openacc.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 
+#include "acc_get_property-aux.h"
+
+
+static void
+expect_device_memory_properties (acc_device_t dev_type, int dev_num,
+				 size_t expected_total_memory)
+{
+  size_t total_mem = acc_get_property (dev_num, dev_type,
+				       acc_property_memory);
+  if (total_mem != expected_total_memory)
+    {
+      fprintf (stderr, "Expected acc_property_memory to equal %zu, "
+	       "but was %zu.\n", expected_total_memory, total_mem);
+      abort ();
+    }
+
+  size_t free_mem = acc_get_property (dev_num, dev_type,
+				      acc_property_free_memory);
+  if (free_mem > total_mem)
+    {
+      fprintf (stderr, "Expected acc_property_free_memory <= acc_property_memory"
+	       ", but free memory was %zu and total memory was %zu.\n",
+	       free_mem, total_mem);
+      abort ();
+    }
+}
 
 void
-expect_device_string_properties (acc_device_t dev_type, int dev_num,
-				 const char* expected_vendor,
-				 const char* expected_name,
-				 const char* expected_driver)
+expect_device_non_memory_properties (acc_device_t dev_type, int dev_num,
+				     const char* expected_vendor,
+				     const char* expected_name,
+				     const char* expected_driver)
 {
   const char *vendor = acc_get_property_string (dev_num, dev_type,
 						acc_property_vendor);
@@ -40,8 +67,8 @@  expect_device_string_properties (acc_device_t dev_type, int dev_num,
       abort ();
     }
 
-  int unknown_property = 16058;
-  size_t v = acc_get_property (dev_num, dev_type, (acc_device_property_t)unknown_property);
+  size_t v = acc_get_property (dev_num, dev_type,
+			       /* unknown */ (acc_device_property_t) 16058);
   if (v != 0)
     {
       fprintf (stderr, "Expected value of unknown numeric property to equal 0, "
@@ -49,8 +76,8 @@  expect_device_string_properties (acc_device_t dev_type, int dev_num,
       abort ();
     }
 
-  int unknown_property2 = -16058;
-  const char *s = acc_get_property_string (dev_num, dev_type, (acc_device_property_t)unknown_property2);
+  const char *s = acc_get_property_string (dev_num, dev_type,
+					   /* unknown */ (acc_device_property_t) -16058);
   if (s != NULL)
     {
       fprintf (stderr, "Expected value of unknown string property to be NULL, "
@@ -59,32 +86,6 @@  expect_device_string_properties (acc_device_t dev_type, int dev_num,
     }
 }
 
-void
-expect_device_memory (acc_device_t dev_type, int dev_num,
-		      size_t expected_total_memory)
-{
-
-  size_t total_mem = acc_get_property (dev_num, dev_type,
-				       acc_property_memory);
-
-  if (total_mem != expected_total_memory)
-    {
-      fprintf (stderr, "Expected acc_property_memory to equal %zu, "
-	       "but was %zu.\n", expected_total_memory, total_mem);
-      abort ();
-    }
-
-  size_t free_mem = acc_get_property (dev_num, dev_type,
-				      acc_property_free_memory);
-  if (free_mem > total_mem)
-    {
-      fprintf (stderr, "Expected acc_property_free_memory <= acc_property_memory"
-	       ", but free memory was %zu and total memory was %zu.\n",
-	       free_mem, total_mem);
-      abort ();
-    }
-}
-
 void
 expect_device_properties (acc_device_t dev_type, int dev_num,
 			  size_t expected_total_memory,
@@ -92,7 +93,8 @@  expect_device_properties (acc_device_t dev_type, int dev_num,
 			  const char* expected_name,
 			  const char* expected_driver)
 {
-  expect_device_string_properties (dev_type, dev_num, expected_vendor,
-				   expected_name, expected_driver);
-  expect_device_memory (dev_type, dev_num, expected_total_memory);
+  expect_device_memory_properties (dev_type, dev_num,
+				    expected_total_memory);
+  expect_device_non_memory_properties (dev_type, dev_num,
+				       expected_vendor, expected_name, expected_driver);
 }
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-aux.h b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-aux.h
new file mode 100644
index 000000000000..b3cfa47ce2eb
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-aux.h
@@ -0,0 +1,14 @@ 
+/* Auxiliary functions for acc_get_property tests */
+
+#include <openacc.h>
+#include <stddef.h>
+
+void expect_device_non_memory_properties (acc_device_t dev_type, int dev_num,
+					  const char* expected_vendor,
+					  const char* expected_name,
+					  const char* expected_driver);
+void expect_device_properties (acc_device_t dev_type, int dev_num,
+			       size_t expected_total_memory,
+			       const char* expected_vendor,
+			       const char* expected_name,
+			       const char* expected_driver);
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-gcn.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-gcn.c
index ce59264a60dc..a09d64749f1b 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-gcn.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-gcn.c
@@ -17,11 +17,8 @@  typedef int bool;
 #endif
 #include <hsa.h>
 
+#include "acc_get_property-aux.h"
 
-void expect_device_string_properties (acc_device_t dev_type, int dev_num,
-				      const char* expected_vendor,
-				      const char* expected_name,
-				      const char* expected_driver);
 
 hsa_status_t (*hsa_agent_get_info_fn) (hsa_agent_t agent,
 				       hsa_agent_info_t attribute,
@@ -114,8 +111,25 @@  check_agent_properties (hsa_agent_t agent, void *dev_num_arg)
   snprintf (driver, sizeof driver, "HSA Runtime %hu.%hu",
 	    (unsigned short int)major, (unsigned short int)minor);
 
-  expect_device_string_properties(acc_device_radeon, *dev_num,
-				  vendor_name, name, driver);
+  expect_device_non_memory_properties (acc_device_default, *dev_num,
+				       vendor_name, name, driver);
+
+  /* Per 'acc_device_t' ordering, the following 'acc_device_not_host' resolves
+     to...  */
+  if (acc_get_num_devices (acc_device_nvidia) > 0)
+    /* ... 'acc_device_nvidia'.  */
+    ;
+  else
+    /* ... 'acc_device_radeon'.  */
+    expect_device_non_memory_properties (acc_device_not_host, *dev_num,
+					 vendor_name, name, driver);
+
+  expect_device_non_memory_properties (acc_device_radeon, *dev_num,
+				       vendor_name, name, driver);
+
+  acc_set_device_num (*dev_num, acc_device_default);
+  expect_device_non_memory_properties (acc_device_current, /* "'devicenum' is ignored" */ 135,
+				       vendor_name, name, driver);
 
   (*dev_num)++;
 
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-host.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-host.c
index 4ed0dfa8886f..c5c006ff3e5a 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-host.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-host.c
@@ -1,20 +1,30 @@ 
-/* Test the `acc_get_property' and '`acc_get_property_string' library
+/* Test the `acc_get_property' and `acc_get_property_string' library
    functions for the host device. */
 /* { dg-additional-sources acc_get_property-aux.c } */
-/* { dg-do run } */
+/* See also '../libgomp.oacc-fortran/acc_get_property-host.F90'.  */
 
 #include <openacc.h>
 #include <stdio.h>
 
-void expect_device_properties (acc_device_t dev_type, int dev_num,
-			       size_t expected_memory,
-			       const char* expected_vendor,
-			       const char* expected_name,
-			       const char* expected_driver);
+#include "acc_get_property-aux.h"
+
 
 int
 main ()
 {
+#if ACC_DEVICE_TYPE_host
+  printf ("Checking acc_device_default device properties\n");
+  expect_device_properties (acc_device_default, 0,
+			    0, "GNU", "GOMP", "1.0");
+#endif
+
   printf ("Checking acc_device_host device properties\n");
-  expect_device_properties (acc_device_host, 0, 0, "GNU", "GOMP", "1.0");
+  expect_device_properties (acc_device_host, 0,
+			    0, "GNU", "GOMP", "1.0");
+
+#if ACC_DEVICE_TYPE_host
+  printf ("Checking acc_device_current device properties\n");
+  expect_device_properties (acc_device_current, /* "'devicenum' is ignored" */ 135,
+			    0, "GNU", "GOMP", "1.0");
+#endif
 }
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-nvptx.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-nvptx.c
index 6334cfdd2f73..109655a1b7d8 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-nvptx.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-nvptx.c
@@ -1,4 +1,4 @@ 
-/* Test the `acc_get_property' and '`acc_get_property_string' library
+/* Test the `acc_get_property' and `acc_get_property_string' library
    functions on Nvidia devices by comparing property values with
    those obtained through the CUDA API. */
 /* { dg-additional-sources acc_get_property-aux.c } */
@@ -11,11 +11,8 @@ 
 #include <string.h>
 #include <stdio.h>
 
-void expect_device_properties (acc_device_t dev_type, int dev_num,
-			       size_t expected_memory,
-			       const char* expected_vendor,
-			       const char* expected_name,
-			       const char* expected_driver);
+#include "acc_get_property-aux.h"
+
 
 int
 main ()
@@ -63,9 +60,23 @@  main ()
       snprintf (driver, sizeof driver, "CUDA Driver %u.%u",
 		driver_version / 1000, driver_version % 1000 / 10);
 
-      /* Note that this check relies on the fact that the device numbering
-	 used by the nvptx plugin agrees with the CUDA device ordering. */
+      /* Note that 'dev_num' usage in the following relies on the fact that the
+	 device numbering used by the libgomp nvptx plugin agrees with the CUDA
+	 device ordering. */
+
+      expect_device_properties (acc_device_default, dev_num,
+				total_mem, vendor, p.name, driver);
+
+      /* Per 'acc_device_t' ordering, the following 'acc_device_not_host'
+	 resolves to 'acc_device_nvidia'.  */
+      expect_device_properties (acc_device_not_host, dev_num,
+				total_mem, vendor, p.name, driver);
+
       expect_device_properties (acc_device_nvidia, dev_num,
 				total_mem, vendor, p.name, driver);
+
+      acc_set_device_num (dev_num, acc_device_default);
+      expect_device_properties (acc_device_current, /* "'devicenum' is ignored" */ 135,
+				total_mem, vendor, p.name, driver);
     }
 }
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property.c
index 3460035f0035..459044d35e53 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property.c
@@ -1,9 +1,8 @@ 
-/* Test the `acc_get_property' and '`acc_get_property_string' library
+/* Test the `acc_get_property' and `acc_get_property_string' library
    functions by printing the results of those functions for all devices
    of all device types mentioned in the OpenACC standard.
 
-   See also acc_get_property.f90. */
-/* { dg-do run } */
+   See also '../libgomp.oacc-fortran/acc_get_property.f90'.  */
 
 #include <openacc.h>
 #include <stdlib.h>
@@ -19,7 +18,13 @@  print_device_properties (acc_device_t type)
   const char *s;
   size_t v;
 
-  int dev_count = acc_get_num_devices (type);
+  int dev_count;
+  if (type != acc_device_current)
+    dev_count = acc_get_num_devices (type);
+  else
+    /* "'devicenum' is ignored and the value of the property for the current
+       device is returned".  We'd like that printed ten times, please.  */
+    dev_count = 10;
 
   for (int i = 0; i < dev_count; ++i)
     {
@@ -73,4 +78,7 @@  main ()
 
   printf ("acc_device_not_host:\n");
   print_device_properties (acc_device_not_host);
+
+  printf ("acc_device_current:\n");
+  print_device_properties (acc_device_current);
 }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc_get_property-aux.f90 b/libgomp/testsuite/libgomp.oacc-fortran/acc_get_property-aux.f90
new file mode 100644
index 000000000000..02f5fbd64fb2
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_get_property-aux.f90
@@ -0,0 +1,102 @@ 
+! Auxiliary functions for acc_get_property tests
+! { dg-do compile { target skip-all-targets } }
+! See also '../libgomp.oacc-c-c++-common/acc_get_property-aux.c'.
+
+module acc_get_property_aux
+  use openacc
+  implicit none
+
+  private
+  public :: expect_device_properties
+
+contains
+
+  subroutine expect_device_memory_properties (dev_type, dev_num, &
+       expected_total_memory)
+    integer, intent(in) :: dev_type
+    integer, intent(in) :: dev_num
+    integer(acc_device_property), intent(in) :: expected_total_memory
+
+    integer(acc_device_property) :: total_mem
+    integer(acc_device_property) :: free_mem
+
+    total_mem = acc_get_property (dev_num, dev_type, &
+         acc_property_memory)
+    if (total_mem /= expected_total_memory) then
+       print *, total_mem, expected_total_memory
+       error stop
+    end if
+
+    free_mem = acc_get_property (dev_num, dev_type, &
+         acc_property_free_memory)
+    if (free_mem .gt. total_mem) then
+       print *, free_mem, total_mem
+       error stop
+    end if
+  end subroutine expect_device_memory_properties
+
+  subroutine expect_device_non_memory_properties (dev_type, dev_num, &
+       expected_vendor, expected_name, expected_driver)
+    integer, intent(in) :: dev_type
+    integer, intent(in) :: dev_num
+    character*(*), intent(in) :: expected_vendor
+    character*(*), intent(in) :: expected_name
+    character*(*), intent(in) :: expected_driver
+
+    character*256 :: vendor
+    character*256 :: name
+    character*256 :: driver
+    integer(acc_device_property) :: v
+    character*256 :: s
+
+    call acc_get_property_string  (dev_num, dev_type, &
+         acc_property_vendor, vendor)
+    if (vendor /= expected_vendor) then
+       print *, vendor, expected_vendor
+       error stop
+    end if
+
+    call acc_get_property_string  (dev_num, dev_type, &
+         acc_property_name, name)
+    if (name /= expected_name) then
+       print *, name, expected_name
+       error stop
+    end if
+
+    call acc_get_property_string  (dev_num, dev_type, &
+         acc_property_driver, driver)
+    if (driver /= expected_driver) then
+       print *, driver, expected_driver
+       error stop
+    end if
+
+    v = acc_get_property (dev_num, dev_type, &
+         int(85061, kind = acc_device_property)) ! unknown
+    if (v /= 0) then
+       print *, v
+       error stop
+    end if
+
+    call acc_get_property_string (dev_num, dev_type, &
+         int(-85061, kind = acc_device_property), s) ! unknown
+    if (s /= "") then
+       print *, s
+       error stop
+    end if
+  end subroutine expect_device_non_memory_properties
+
+  subroutine expect_device_properties (dev_type, dev_num, &
+       expected_total_memory, expected_vendor, expected_name, expected_driver)
+    integer, intent(in) :: dev_type
+    integer, intent(in) :: dev_num
+    integer(acc_device_property), intent(in) :: expected_total_memory
+    character*(*), intent(in) :: expected_vendor
+    character*(*), intent(in) :: expected_name
+    character*(*), intent(in) :: expected_driver
+
+    call expect_device_memory_properties (dev_type, dev_num, &
+         expected_total_memory)
+    call expect_device_non_memory_properties (dev_type, dev_num, &
+         expected_vendor, expected_name, expected_driver)
+  end subroutine expect_device_properties
+end module acc_get_property_aux
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc_get_property-host.F90 b/libgomp/testsuite/libgomp.oacc-fortran/acc_get_property-host.F90
new file mode 100644
index 000000000000..3394fb74141b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_get_property-host.F90
@@ -0,0 +1,31 @@ 
+! Test the `acc_get_property' and `acc_get_property_string' library
+! functions for the host device.
+! See also '../libgomp.oacc-c-c++-common/acc_get_property-host.c'.
+
+! The libgomp test harness doesn't make it easy to use modules in separate
+! compilation units, so work around that: simply 'include' the file.
+include "acc_get_property-aux.f90"
+
+program test
+  use acc_get_property_aux
+  use openacc
+  implicit none
+
+#if ACC_DEVICE_TYPE_host
+  print *, "Checking acc_device_default device properties"
+  call expect_device_properties (acc_device_default, 0, &
+      int(0, kind = acc_device_property), "GNU", "GOMP", "1.0")
+#endif
+
+  print *, "Checking acc_device_host device properties"
+  call expect_device_properties (acc_device_host, 0, &
+      int(0, kind = acc_device_property), "GNU", "GOMP", "1.0")
+
+#if ACC_DEVICE_TYPE_host
+  print *, "Checking acc_device_current device properties"
+  call expect_device_properties (acc_device_current, 135, & ! "'devicenum' is ignored"
+      int(0, kind = acc_device_property), "GNU", "GOMP", "1.0")
+#endif
+end program test
+
+! { dg-final { cleanup-modules "acc_get_property_aux" } }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc_get_property.f90 b/libgomp/testsuite/libgomp.oacc-fortran/acc_get_property.f90
index 80ae292f41fc..dd387683ff97 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/acc_get_property.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_get_property.f90
@@ -1,8 +1,8 @@ 
-! Test the `acc_get_property' and '`acc_get_property_string' library
+! Test the `acc_get_property' and `acc_get_property_string' library
 ! functions by printing the results of those functions for all devices
 ! of all device types mentioned in the OpenACC standard.
 !
-! See also acc_get_property.c
+! See also '../libgomp.oacc-c-c++-common/acc_get_property.c'.
 
 program test
   use openacc
@@ -20,6 +20,9 @@  program test
 
   print *, "acc_device_not_host:"
   call print_device_properties (acc_device_not_host)
+
+  print *, "acc_device_current:"
+  call print_device_properties (acc_device_current)
 end program test
 
 ! Print the values of the properties of all devices of the given type
@@ -35,7 +38,13 @@  subroutine print_device_properties (device_type)
   integer(acc_device_property) :: v
   character*256 :: s
 
-  device_count = acc_get_num_devices(device_type)
+  if (device_type /= acc_device_current) then
+     device_count = acc_get_num_devices (device_type)
+  else
+     ! "'devicenum' is ignored and the value of the property for the current
+     ! device is returned".  We'd like that printed ten times, please.
+     device_count = 10
+  end if
 
   do device = 0, device_count - 1
      print "(a, i0)", "  Device ", device
-- 
2.17.1