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
@@ -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)
@@ -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
@@ -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);
}
new file mode 100644
@@ -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);
@@ -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)++;
@@ -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
}
@@ -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);
}
}
@@ -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);
}
new file mode 100644
@@ -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
new file mode 100644
@@ -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" } }
@@ -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