From 41f36f22f38285fef3b2166a00d4ec446fb96125 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Mon, 9 Dec 2019 12:40:36 +0100 Subject: [PATCH] [PR92511] More testing for OpenACC "present" subarrays In particular, "subset subarrays". libgomp/ PR libgomp/92511 * testsuite/libgomp.oacc-c-c++-common/copyin-devptr-1.c: Remove this file... * testsuite/libgomp.oacc-c-c++-common/copyin-devptr-2.c: ..., and this file... * testsuite/libgomp.oacc-c-c++-common/lib-22.c: ..., and this file... * testsuite/libgomp.oacc-c-c++-common/lib-30.c: ..., and this file... * testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-r-p.c: ... with their content moved into, and extended in this new file. * testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-d-a.c: New file. * testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-d-p.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-r-a.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-2.c: Likewise. From-SVN: r279122 --- libgomp/ChangeLog | 20 + .../copyin-devptr-1.c | 28 - .../copyin-devptr-2.c | 35 -- .../libgomp.oacc-c-c++-common/lib-22.c | 33 -- .../libgomp.oacc-c-c++-common/lib-30.c | 30 - .../subset-subarray-mappings-1-d-a.c | 7 + .../subset-subarray-mappings-1-d-p.c | 7 + .../subset-subarray-mappings-1-r-a.c | 7 + .../subset-subarray-mappings-1-r-p.c | 514 ++++++++++++++++++ .../subset-subarray-mappings-2.c | 115 ++++ 10 files changed, 670 insertions(+), 126 deletions(-) delete mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-1.c delete mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-2.c delete mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/lib-22.c delete mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/lib-30.c create mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-d-a.c create mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-d-p.c create mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-r-a.c create mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-r-p.c create mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-2.c diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 51a00a3a46c..739a76d48ac 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,5 +1,25 @@ 2019-12-09 Thomas Schwinge + PR libgomp/92511 + * testsuite/libgomp.oacc-c-c++-common/copyin-devptr-1.c: Remove + this file... + * testsuite/libgomp.oacc-c-c++-common/copyin-devptr-2.c: ..., and + this file... + * testsuite/libgomp.oacc-c-c++-common/lib-22.c: ..., and this + file... + * testsuite/libgomp.oacc-c-c++-common/lib-30.c: ..., and this + file... + * testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-r-p.c: + ... with their content moved into, and extended in this new file. + * testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-d-a.c: + New file. + * testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-d-p.c: + Likewise. + * testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-r-a.c: + Likewise. + * testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-2.c: + Likewise. + * testsuite/libgomp.oacc-c-c++-common/map-data-1.c: New file. PR libgomp/92854 diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-1.c deleted file mode 100644 index 7e50f3b892e..00000000000 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-1.c +++ /dev/null @@ -1,28 +0,0 @@ -/* { dg-skip-if "" { *-*-* } { "-DACC_MEM_SHARED=1" } } */ - -#include -#include -#include -#include - -int main (int argc, char* argv[]) -{ - char *myblock = (char *) malloc (1024); - int i; - void *dst; - for (i = 0; i < 1024; i++) - myblock[i] = i; - dst = acc_copyin (myblock, 1024); - for (i = 0; i < 1024; i += 256) - { - void *partdst = acc_pcopyin (&myblock[i], 256); - assert ((uintptr_t) partdst == (uintptr_t) dst + i); - } - for (i = 0; i < 1024; i += 256) - acc_delete (&myblock[i], 256); - assert (acc_is_present (myblock, 1024)); - acc_delete (myblock, 1024); - assert (!acc_is_present (myblock, 1024)); - free (myblock); - return 0; -} diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-2.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-2.c deleted file mode 100644 index 00e7da1f128..00000000000 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-2.c +++ /dev/null @@ -1,35 +0,0 @@ -/* { dg-skip-if "" { *-*-* } { "-DACC_MEM_SHARED=1" } } */ - -#include -#include -#include -#include - -int main (int argc, char* argv[]) -{ - char *block1 = (char *) malloc (1024); - char *block2 = (char *) malloc (1024); - char *block3 = (char *) malloc (1024); - int i; - void *dst; - for (i = 0; i < 1024; i++) - block1[i] = block2[i] = block3[i] = i; - #pragma acc data copyin(block1[0:1024]) copyin(block2[0:1024]) \ - copyin(block3[0:1024]) - { - dst = acc_deviceptr (block2); - for (i = 0; i < 1024; i += 256) - { - void *partdst = acc_pcopyin (&block2[i], 256); - assert ((uintptr_t) partdst == (uintptr_t) dst + i); - } - } - assert (acc_is_present (block2, 1024)); - for (i = 0; i < 1024; i += 256) - acc_delete (&block2[i], 256); - assert (!acc_is_present (block2, 1024)); - free (block1); - free (block2); - free (block3); - return 0; -} diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-22.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-22.c deleted file mode 100644 index cb32bbcb652..00000000000 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-22.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Exercise acc_copyin and acc_copyout on nvidia targets. */ - -/* { dg-do run { target openacc_nvidia_accel_selected } } */ - -#include -#include -#include - -int -main (int argc, char **argv) -{ - const int N = 256; - int i; - unsigned char *h; - - h = (unsigned char *) malloc (N); - - for (i = 0; i < N; i++) - { - h[i] = i; - } - - (void) acc_copyin (h, N); - - fprintf (stderr, "CheCKpOInT\n"); - acc_copyout (h + 1, N - 1); - - free (h); - - return 0; -} - -/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */ diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-30.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-30.c deleted file mode 100644 index d0e5ffb0691..00000000000 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-30.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Exercise an invalid partial acc_delete on nvidia targets. */ - -/* { dg-do run { target openacc_nvidia_accel_selected } } */ - -#include -#include -#include - -int -main (int argc, char **argv) -{ - const int N = 256; - unsigned char *h; - void *d; - - h = (unsigned char *) malloc (N); - - d = acc_create (h, N); - if (!d) - abort (); - - fprintf (stderr, "CheCKpOInT\n"); - acc_delete (h, N - 2); - - free (h); - - return 0; -} - -/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */ diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-d-a.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-d-a.c new file mode 100644 index 00000000000..1d168c2e585 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-d-a.c @@ -0,0 +1,7 @@ +/* Test "subset" subarray mappings + { dg-additional-options "-DOPENACC_DIRECTIVES" } using OpenACC directives, + { dg-additional-options "-DARRAYS" } using arrays. */ + +/* { dg-skip-if "" { *-*-* } { "-DACC_MEM_SHARED=1" } } */ + +#include "subset-subarray-mappings-1-r-p.c" diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-d-p.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-d-p.c new file mode 100644 index 00000000000..68ed0ce3eca --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-d-p.c @@ -0,0 +1,7 @@ +/* Test "subset" subarray mappings + { dg-additional-options "-DOPENACC_DIRECTIVES" } using OpenACC directives, + { dg-additional-options "-DPOINTERS" } using pointers. */ + +/* { dg-skip-if "" { *-*-* } { "-DACC_MEM_SHARED=1" } } */ + +#include "subset-subarray-mappings-1-r-p.c" diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-r-a.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-r-a.c new file mode 100644 index 00000000000..5c0fd040d87 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-r-a.c @@ -0,0 +1,7 @@ +/* Test "subset" subarray mappings + { dg-additional-options "-DOPENACC_RUNTIME" } using OpenACC Runtime Library routines, + { dg-additional-options "-DARRAYS" } using arrays. */ + +/* { dg-skip-if "" { *-*-* } { "-DACC_MEM_SHARED=1" } } */ + +#include "subset-subarray-mappings-1-r-p.c" diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-r-p.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-r-p.c new file mode 100644 index 00000000000..9b5d83c66dd --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-1-r-p.c @@ -0,0 +1,514 @@ +/* Test "subset" subarray mappings + { dg-additional-options "-DOPENACC_RUNTIME" } using OpenACC Runtime Library routines, + { dg-additional-options "-DPOINTERS" } using pointers. */ + +/* { dg-skip-if "" { *-*-* } { "-DACC_MEM_SHARED=1" } } */ + +#if OPENACC_RUNTIME +#elif OPENACC_DIRECTIVES +#else +# error +#endif + +#if POINTERS +#elif ARRAYS +#else +# error +#endif + + +#include +#include +#include +#include +#include +#include +#include + + +static bool cb_ev_alloc_expected; +static size_t cb_ev_alloc_bytes; +static const void *cb_ev_alloc_device_ptr; +static void +cb_ev_alloc (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info) +{ + assert (cb_ev_alloc_expected); + cb_ev_alloc_expected = false; + + cb_ev_alloc_bytes = event_info->data_event.bytes; + cb_ev_alloc_device_ptr = event_info->data_event.device_ptr; +} + +static bool cb_ev_free_expected; +static const void *cb_ev_free_device_ptr; +static void +cb_ev_free (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info) +{ + assert (cb_ev_free_expected); + cb_ev_free_expected = false; + + cb_ev_free_device_ptr = event_info->data_event.device_ptr; +} + + +/* Match the alignment processing that + 'libgomp/target.c:gomp_map_vars_internal' is doing; simplified, not + considering special alignment requirements of certain data types. */ + +static size_t +aligned_size (size_t tgt_size) +{ + size_t tgt_align = sizeof (void *); + return tgt_size + tgt_align - 1; +} + +static const void * +aligned_address (const void *tgt_start) +{ + size_t tgt_align = sizeof (void *); + return (void *) (((uintptr_t) tgt_start + tgt_align - 1) & ~(tgt_align - 1)); +} + + +#define SIZE 1024 +#define SUBSET 32 + + +static void +f1 (void) +{ + cb_ev_alloc_expected = false; + cb_ev_free_expected = false; + acc_prof_register (acc_ev_alloc, cb_ev_alloc, acc_reg); + acc_prof_register (acc_ev_free, cb_ev_free, acc_reg); + +#if POINTERS + char* myblock = (char *) malloc (SIZE); +#else + char myblock[SIZE]; +#endif + int i; + void *dst; + for (i = 0; i < SIZE; i++) + myblock[i] = i; + + cb_ev_alloc_expected = true; +#if OPENACC_RUNTIME + dst = acc_copyin (myblock, SIZE); +#else +# if POINTERS +# pragma acc enter data copyin (myblock[0:SIZE]) +# else +# pragma acc enter data copyin (myblock) +# endif + dst = acc_deviceptr (myblock); +#endif + assert (dst); + assert (!cb_ev_alloc_expected); + assert (cb_ev_alloc_bytes == aligned_size (SIZE)); + assert (aligned_address (cb_ev_alloc_device_ptr) == dst); + for (i = 0; i < SIZE; i += SUBSET) + { + void *partdst = acc_deviceptr (&myblock[i]); + assert ((uintptr_t) partdst == (uintptr_t) dst + i); + assert (acc_hostptr (partdst) == &myblock[i]); + } + for (i = 0; i < SIZE; i += SUBSET) + { + void *partdst; +#if OPENACC_RUNTIME + partdst = acc_pcopyin (&myblock[i], SUBSET); +#else +# pragma acc enter data pcopyin (myblock[i:SUBSET]) + partdst = acc_deviceptr (&myblock[i]); +#endif + assert ((uintptr_t) partdst == (uintptr_t) dst + i); + } + /* Dereference first half. */ + for (i = 0; i < 512; i += SUBSET) + { + assert (acc_is_present (&myblock[i], SUBSET)); + assert (acc_is_present (myblock, SIZE)); +#if OPENACC_RUNTIME + acc_delete (&myblock[i], SUBSET); +#else +# pragma acc exit data delete (myblock[i:SUBSET]) +#endif + assert (acc_is_present (&myblock[i], SUBSET)); + assert (acc_is_present (myblock, SIZE)); + } + /* Dereference all. */ +#if OPENACC_RUNTIME + acc_delete (myblock, SIZE); +#else +# if POINTERS +# pragma acc exit data delete (myblock[0:SIZE]) +# else +# pragma acc exit data delete (myblock) +# endif +#endif + /* Expect it's still present. */ + assert (acc_is_present (myblock, SIZE)); + /* Dereference second half. */ + for (i = 512; i < SIZE; i += SUBSET) + { + bool last = i >= SIZE - SUBSET; + + assert (acc_is_present (&myblock[i], SUBSET)); + assert (acc_is_present (myblock, SIZE)); +#if 0 //TODO PR92848 + if (last) + cb_ev_free_expected = true; +#endif +#if OPENACC_RUNTIME + acc_delete (&myblock[i], SUBSET); +#else +# pragma acc exit data delete (myblock[i:SUBSET]) +#endif +#if 0 //TODO PR92848 + assert (!cb_ev_free_expected); + if (last) + assert (cb_ev_free_device_ptr == cb_ev_alloc_device_ptr); +#endif + assert (acc_is_present (&myblock[i], SUBSET) != last); + assert (acc_is_present (myblock, SIZE) != last); + } + /* Expect it's all gone now. */ + for (i = 512; i < SIZE; i += SUBSET) + assert (!acc_is_present (&myblock[i], SUBSET)); + assert (!acc_is_present (myblock, SIZE)); + assert (!acc_is_present (myblock, 1)); + +#if POINTERS + free (myblock); +#endif + + acc_prof_unregister (acc_ev_alloc, cb_ev_alloc, acc_reg); + acc_prof_unregister (acc_ev_free, cb_ev_free, acc_reg); +} + + +static void +f2 (void) +{ + cb_ev_alloc_expected = false; + cb_ev_free_expected = false; + acc_prof_register (acc_ev_alloc, cb_ev_alloc, acc_reg); + acc_prof_register (acc_ev_free, cb_ev_free, acc_reg); + +#if POINTERS + char *block1 = (char *) malloc (SIZE); + char *block2 = (char *) malloc (SIZE); + char *block3 = (char *) malloc (SIZE); +#else + char block1[SIZE]; + char block2[SIZE]; + char block3[SIZE]; +#endif + int i; + for (i = 0; i < SIZE; i++) + block1[i] = block2[i] = block3[i] = i; + + cb_ev_alloc_expected = true; +#if POINTERS +# pragma acc data copyin(block1[0:SIZE], block2[0:SIZE], block3[0:SIZE]) +#else +# pragma acc data copyin(block1, block2, block3) +#endif + { + void *block1_d = acc_deviceptr (block1); + void *block2_d = acc_deviceptr (block2); + void *block3_d = acc_deviceptr (block3); + assert (!cb_ev_alloc_expected); + /* 'block1', 'block2', 'block3' get mapped in one device memory object, in + reverse order. */ + assert (cb_ev_alloc_bytes == aligned_size (3 * SIZE)); + assert ((void *) ((uintptr_t) aligned_address (cb_ev_alloc_device_ptr) + 2 * SIZE) == block1_d); + assert ((void *) ((uintptr_t) aligned_address (cb_ev_alloc_device_ptr) + 1 * SIZE) == block2_d); + assert ((void *) ((uintptr_t) aligned_address (cb_ev_alloc_device_ptr) + 0 * SIZE) == block3_d); + + for (i = 0; i < SIZE; i += SUBSET) + { + void *block2_part_d; +#if OPENACC_RUNTIME + block2_part_d = acc_pcopyin (&block2[i], SUBSET); +#else +# pragma acc enter data pcopyin (block2[i:SUBSET]) + block2_part_d = acc_deviceptr (&block2[i]); +#endif + assert ((uintptr_t) block2_part_d == (uintptr_t) block2_d + i); + } + } + /* The mappings have been removed, but the device memory object has not yet + been 'free'd. */ + assert (!acc_is_present (block1, SIZE)); + assert (acc_is_present (block2, SIZE)); + assert (!acc_is_present (block3, SIZE)); + for (i = 0; i < SIZE; i += SUBSET) + { + bool last = i >= SIZE - SUBSET; + + assert (acc_is_present (block2, SIZE)); + if (last) + cb_ev_free_expected = true; +#if OPENACC_RUNTIME + acc_delete (&block2[i], SUBSET); +#else +# pragma acc exit data delete (block2[i:SUBSET]) +#endif + assert (!cb_ev_free_expected); + if (last) + assert (cb_ev_free_device_ptr == cb_ev_alloc_device_ptr); + } + assert (!acc_is_present (block1, SIZE)); + assert (!acc_is_present (block2, SIZE)); + assert (!acc_is_present (block3, SIZE)); + +#if POINTERS + free (block1); + free (block2); + free (block3); +#endif + + acc_prof_unregister (acc_ev_alloc, cb_ev_alloc, acc_reg); + acc_prof_unregister (acc_ev_free, cb_ev_free, acc_reg); +} + + +static void +f3 () +{ + cb_ev_alloc_expected = false; + cb_ev_free_expected = false; + acc_prof_register (acc_ev_alloc, cb_ev_alloc, acc_reg); + acc_prof_register (acc_ev_free, cb_ev_free, acc_reg); + +#if POINTERS + char *h = (char *) malloc (SIZE); +#else + char h[SIZE]; +#endif + + char *d1; + cb_ev_alloc_expected = true; +#if OPENACC_RUNTIME + d1 = (char *) acc_present_or_create (h, SIZE); +#else +# if POINTERS +# pragma acc enter data present_or_create (h[0:SIZE]) +# else +# pragma acc enter data present_or_create (h) +# endif + d1 = (char *) acc_deviceptr (h); +#endif + assert (d1); + assert (!cb_ev_alloc_expected); + assert (cb_ev_alloc_bytes == aligned_size (SIZE)); + assert (aligned_address (cb_ev_alloc_device_ptr) == d1); + assert (acc_is_present (h, SIZE)); + assert (acc_is_present (&h[2], SIZE - 2)); + + char *d2; +#if OPENACC_RUNTIME + d2 = (char *) acc_present_or_create (&h[2], SIZE - 2); +#else +# pragma acc enter data present_or_create (h[2:SIZE - 2]) + d2 = (char *) acc_deviceptr (&h[2]); +#endif + assert (d2); + assert (d1 == d2 - 2); + assert (acc_is_present (h, SIZE)); + assert (acc_is_present (&h[2], SIZE - 2)); + + d2 = (char *) acc_deviceptr (&h[2]); + assert (d1 == d2 - 2); + +#if OPENACC_RUNTIME + acc_delete (&h[2], SIZE - 2); +#else +# pragma acc exit data delete (h[2:SIZE - 2]) +#endif + assert (acc_is_present (h, SIZE)); + assert (acc_is_present (&h[2], SIZE - 2)); + +#if 0 //TODO PR92848 + cb_ev_free_expected = true; +#endif +#if OPENACC_RUNTIME + acc_delete (h, SIZE); +#else +# if POINTERS +# pragma acc exit data delete (h[0:SIZE]) +# else +# pragma acc exit data delete (h) +# endif +#endif +#if 0 //TODO PR92848 + assert (!cb_ev_free_expected); + assert (cb_ev_free_device_ptr == cb_ev_alloc_device_ptr); +#endif + + assert (!acc_is_present (h, SIZE)); + assert (!acc_is_present (&h[2], SIZE - 2)); + assert (!acc_is_present (h, 1)); + +# if POINTERS + free (h); +#endif + + acc_prof_unregister (acc_ev_alloc, cb_ev_alloc, acc_reg); + acc_prof_unregister (acc_ev_free, cb_ev_free, acc_reg); +} + + +/* Based on what used to be 'libgomp.oacc-c-c++-common/lib-22.c'. */ + +static void +f_lib_22 (void) +{ + cb_ev_alloc_expected = false; + cb_ev_free_expected = false; + acc_prof_register (acc_ev_alloc, cb_ev_alloc, acc_reg); + acc_prof_register (acc_ev_free, cb_ev_free, acc_reg); + + const int c0 = 0; + const int c1 = 1; + +#if POINTERS + char *h = (char *) malloc (SIZE); +#else + char h[SIZE]; +#endif + + memset (h, c0, SIZE); + void *d; + cb_ev_alloc_expected = true; +#if OPENACC_RUNTIME + d = acc_copyin (h, SIZE); +#else +# if POINTERS +# pragma acc enter data copyin (h[0:SIZE]) +# else +# pragma acc enter data copyin (h) +# endif + d = acc_deviceptr (h); +#endif + assert (d); + assert (!cb_ev_alloc_expected); + assert (cb_ev_alloc_bytes == aligned_size (SIZE)); + assert (aligned_address (cb_ev_alloc_device_ptr) == d); + /* Overwrite the local memory. */ + memset (h, c1, SIZE); + /* Now 'copyout' not the whole but only a "subset" subarray, missing one + SUBSET at the beginning, and half a SUBSET at the end... */ +#if 0 //TODO PR92848 + cb_ev_free_expected = true; +#endif +#if OPENACC_RUNTIME + acc_copyout (h + SUBSET, SIZE - SUBSET - SUBSET / 2); +#else +# pragma acc exit data copyout (h[SUBSET:SIZE - SUBSET - SUBSET / 2]) +#endif +#if 0 //TODO PR92848 + /* ..., yet, expect the device memory object to be 'free'd... */ + assert (!cb_ev_free_expected); + assert (cb_ev_free_device_ptr == cb_ev_alloc_device_ptr); +#endif + /* ..., and the mapping to be removed... */ + assert (!acc_is_present (h, SIZE)); + assert (!acc_is_present (&h[SUBSET], SIZE - SUBSET - SUBSET / 2)); + assert (!acc_is_present (h, 1)); + /* ..., but the 'copyout'ed device memory to correspond to just the "subset" + subarray. */ + for (size_t i = 0; i < SIZE; ++i) + { + if (i < SUBSET) + assert (h[i] == c1); + else if (i < SIZE - SUBSET / 2) + assert (h[i] == c0); + else if (i < SIZE) + assert (h[i] == c1); + } + +#if POINTERS + free (h); +#endif + + acc_prof_unregister (acc_ev_alloc, cb_ev_alloc, acc_reg); + acc_prof_unregister (acc_ev_free, cb_ev_free, acc_reg); +} + + +/* Based on what used to be 'libgomp.oacc-c-c++-common/lib-30.c'. */ + +static void +f_lib_30 (void) +{ + cb_ev_alloc_expected = false; + cb_ev_free_expected = false; + acc_prof_register (acc_ev_alloc, cb_ev_alloc, acc_reg); + acc_prof_register (acc_ev_free, cb_ev_free, acc_reg); + +#if POINTERS + char *h = (char *) malloc (SIZE); +#else + char h[SIZE]; +#endif + memset (h, 0, SIZE); + + void *d; + cb_ev_alloc_expected = true; +#if OPENACC_RUNTIME + d = acc_create (h, SIZE); +#else +# if POINTERS +# pragma acc enter data create (h[0:SIZE]) +# else +# pragma acc enter data create (h) +# endif + d = acc_deviceptr (h); +#endif + assert (d); + assert (!cb_ev_alloc_expected); + assert (cb_ev_alloc_bytes == aligned_size (SIZE)); + assert (aligned_address (cb_ev_alloc_device_ptr) == d); + + /* We 'delete' not the whole but only a "subset" subarray... */ +#if 0 //TODO PR92848 + cb_ev_free_expected = true; +#endif +#if OPENACC_RUNTIME + acc_delete (h, SIZE - SUBSET); +#else +# pragma acc exit data delete (h[0:SIZE - SUBSET]) +#endif +#if 0 //TODO PR92848 + /* ..., yet, expect the device memory object to be 'free'd... */ + assert (!cb_ev_free_expected); + assert (cb_ev_free_device_ptr == cb_ev_alloc_device_ptr); +#endif + /* ..., and the mapping to be removed. */ + assert (!acc_is_present (h, SIZE)); + assert (!acc_is_present (h, SIZE - SUBSET)); + assert (!acc_is_present (h, 1)); + +#if POINTERS + free (h); +#endif + + acc_prof_unregister (acc_ev_alloc, cb_ev_alloc, acc_reg); + acc_prof_unregister (acc_ev_free, cb_ev_free, acc_reg); +} + + +int +main () +{ + f1 (); + f2 (); + f3 (); + f_lib_22 (); + f_lib_30 (); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-2.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-2.c new file mode 100644 index 00000000000..f4e18fa97a7 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/subset-subarray-mappings-2.c @@ -0,0 +1,115 @@ +/* Test "subset" subarray mappings. */ + +/* { dg-skip-if "" { *-*-* } { "-DACC_MEM_SHARED=1" } } */ + +#include +#include +#include +#include +#include +#include + + +static bool cb_ev_alloc_expected; +static size_t cb_ev_alloc_bytes; +static const void *cb_ev_alloc_device_ptr; +static void +cb_ev_alloc (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info) +{ + assert (cb_ev_alloc_expected); + cb_ev_alloc_expected = false; + + cb_ev_alloc_bytes = event_info->data_event.bytes; + cb_ev_alloc_device_ptr = event_info->data_event.device_ptr; +} + +static bool cb_ev_free_expected; +static const void *cb_ev_free_device_ptr; +static void +cb_ev_free (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info) +{ + assert (cb_ev_free_expected); + cb_ev_free_expected = false; + + cb_ev_free_device_ptr = event_info->data_event.device_ptr; +} + + +/* Match the alignment processing that + 'libgomp/target.c:gomp_map_vars_internal' is doing; simplified, not + considering special alignment requirements of certain data types. */ + +static size_t +aligned_size (size_t tgt_size) +{ + size_t tgt_align = sizeof (void *); + return tgt_size + tgt_align - 1; +} + +static const void * +aligned_address (const void *tgt_start) +{ + size_t tgt_align = sizeof (void *); + return (void *) (((uintptr_t) tgt_start + tgt_align - 1) & ~(tgt_align - 1)); +} + + +#define SIZE 1024 + + +int +main () +{ + cb_ev_alloc_expected = false; + cb_ev_free_expected = false; + acc_prof_register (acc_ev_alloc, cb_ev_alloc, acc_reg); + acc_prof_register (acc_ev_free, cb_ev_free, acc_reg); + + char *block1 = (char *) malloc (SIZE); + char *block2 = (char *) malloc (SIZE); + char *block3 = (char *) malloc (SIZE); + cb_ev_alloc_expected = true; +#pragma acc data create (block1[0:SIZE], block2[0:SIZE], block3[0:SIZE]) + { + void *s_block1_d = acc_deviceptr (&block1[1]); + void *s_block2_d = acc_deviceptr (&block2[20]); + void *s_block3_d = acc_deviceptr (&block3[300]); + assert (!cb_ev_alloc_expected); + /* 'block1', 'block2', 'block3' get mapped in one device memory object, in + reverse order. */ + assert (cb_ev_alloc_bytes == aligned_size (3 * SIZE)); + assert ((void *) ((uintptr_t) aligned_address (cb_ev_alloc_device_ptr) + 2 * SIZE + 1) == s_block1_d); + assert ((void *) ((uintptr_t) aligned_address (cb_ev_alloc_device_ptr) + 1 * SIZE + 20) == s_block2_d); + assert ((void *) ((uintptr_t) aligned_address (cb_ev_alloc_device_ptr) + 0 * SIZE + 300) == s_block3_d); + + void *s_block1_p_d = acc_pcopyin (&block1[1], SIZE - 3); + void *s_block2_p_d = acc_pcopyin (&block2[20], SIZE - 33); + void *s_block3_p_d = acc_pcopyin (&block3[300], SIZE - 333); + assert (s_block1_p_d == s_block1_d); + assert (s_block2_p_d == s_block2_d); + assert (s_block3_p_d == s_block3_d); + + acc_delete (block1, SIZE); + acc_delete (block2, SIZE); + acc_delete (block3, SIZE); + assert (acc_is_present (block1, SIZE)); + assert (acc_is_present (block2, SIZE)); + assert (acc_is_present (block3, SIZE)); + + cb_ev_free_expected = true; + } + assert (!cb_ev_free_expected); + assert (cb_ev_free_device_ptr == cb_ev_alloc_device_ptr); + assert (!acc_is_present (block1, SIZE)); + assert (!acc_is_present (block2, SIZE)); + assert (!acc_is_present (block3, SIZE)); + + free (block1); + free (block2); + free (block3); + + acc_prof_unregister (acc_ev_alloc, cb_ev_alloc, acc_reg); + acc_prof_unregister (acc_ev_free, cb_ev_free, acc_reg); + + return 0; +} -- 2.30.2