From 5ce3725cf160f086e99c01e73c26a0bf5654f5b6 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge 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 #include #include #include +#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 +#include + +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 +#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 #include -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 #include -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 #include @@ -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