/* { dg-require-effective-target offload_device_nonshared_as } */ #include #include #define N 40 int sum; int var1 = 1; int var2 = 2; #pragma omp declare target int D[N]; #pragma omp end declare target void enter_data (int *X) { #pragma omp target enter data map(to: var1, var2, X[:N]) map(alloc: sum) } void exit_data_0 (int *D) { #pragma omp target exit data map(delete: D[:N]) } void exit_data_1 () { #pragma omp target exit data map(from: var1) } void exit_data_2 (int *X) { #pragma omp target exit data map(from: var2) map(release: X[:N], sum) } void exit_data_3 (int *p) { #pragma omp target exit data map(from: p[:0]) } void test_nested () { int X = 0, Y = 0, Z = 0; #pragma omp target data map(from: X, Y, Z) { #pragma omp target data map(from: X, Y, Z) { #pragma omp target map(from: X, Y, Z) X = Y = Z = 1337; assert (X == 0); assert (Y == 0); assert (Z == 0); #pragma omp target exit data map(from: X) map(release: Y) assert (X == 0); assert (Y == 0); #pragma omp target exit data map(release: Y) map(delete: Z) assert (Y == 0); assert (Z == 0); } assert (X == 1337); assert (Y == 0); assert (Z == 0); #pragma omp target map(from: X) X = 2448; assert (X == 2448); assert (Y == 0); assert (Z == 0); X = 4896; } assert (X == 4896); assert (Y == 0); assert (Z == 0); } int main () { int *X = malloc (N * sizeof (int)); int *Y = malloc (N * sizeof (int)); X[10] = 10; Y[20] = 20; enter_data (X); exit_data_0 (D); /* This should have no effect on D. */ #pragma omp target map(alloc: var1, var2, X[:N]) map(to: Y[:N]) map(always from: sum) { var1 += X[10]; var2 += Y[20]; sum = var1 + var2; D[sum]++; } assert (var1 == 1); assert (var2 == 2); assert (sum == 33); exit_data_1 (); assert (var1 == 11); assert (var2 == 2); /* Increase refcount of already mapped X[0:N]. */ #pragma omp target enter data map(alloc: X[16:1]) exit_data_2 (X); assert (var2 == 22); exit_data_3 (X + 5); /* Unmap X[0:N]. */ free (X); free (Y); test_nested (); return 0; }