blob: 54507176cf03a694ba3ae93f4125957b30f65413 [file]
// Test multiple map clauses for the same variable using pointer array sections
// and C++ references.
// { dg-do run }
extern "C" void abort ();
static const int N = 100;
/* Test fixed-size array with multiple map clauses. */
static void
test_pointer ()
{
int p[N];
/* map(to) + map(alloc) + map(from): three clauses on the same array. */
for (int i = 0; i < N; i++) p[i] = i;
#pragma omp target map(to: p) map(alloc: p) map(from: p)
for (int i = 0; i < N; i++) p[i] *= 4;
for (int i = 0; i < N; i++) if (p[i] != i * 4) abort ();
/* map(to) + map(tofrom): tofrom covers both directions. */
for (int i = 0; i < N; i++) p[i] = i;
#pragma omp target map(to: p) map(tofrom: p)
for (int i = 0; i < N; i++) p[i] *= 5;
for (int i = 0; i < N; i++) if (p[i] != i * 5) abort ();
/* map(alloc) + map(to): device gets host values via 'to'. */
for (int i = 0; i < N; i++) p[i] = i;
int sum = 0;
#pragma omp target map(alloc: p) map(to: p) map(tofrom: sum)
for (int i = 0; i < N; i++) sum += p[i];
if (sum != N * (N - 1) / 2) abort ();
/* map(alloc) + map(from): device values come back via 'from'. */
#pragma omp target map(alloc: p) map(from: p)
for (int i = 0; i < N; i++) p[i] = i * 7;
for (int i = 0; i < N; i++) if (p[i] != i * 7) abort ();
/* map(alloc) + map(tofrom) + map(alloc): three clauses, full bidirectional. */
for (int i = 0; i < N; i++) p[i] = i;
#pragma omp target map(alloc: p) map(tofrom: p) map(alloc: p)
for (int i = 0; i < N; i++) p[i] *= 8;
for (int i = 0; i < N; i++) if (p[i] != i * 8) abort ();
}
/* Test C++ array references: r aliases a. */
static void
test_reference ()
{
int a[N];
int (&r)[N] = a;
/* map(to: r) + map(from: r): send and receive via the same reference. */
for (int i = 0; i < N; i++) a[i] = i;
#pragma omp target map(to: r) map(from: r)
for (int i = 0; i < N; i++) r[i] *= 4;
for (int i = 0; i < N; i++) if (r[i] != i * 4) abort ();
/* map(to: r) + map(tofrom: r): to and tofrom on the same reference. */
for (int i = 0; i < N; i++) a[i] = i;
#pragma omp target map(to: r) map(tofrom: r)
for (int i = 0; i < N; i++) r[i] *= 5;
for (int i = 0; i < N; i++) if (r[i] != i * 5) abort ();
/* map(to: r) + map(alloc: r) + map(from: r): three clauses on the same reference. */
for (int i = 0; i < N; i++) a[i] = i;
#pragma omp target map(to: r) map(alloc: r) map(from: r)
for (int i = 0; i < N; i++) r[i] *= 6;
for (int i = 0; i < N; i++) if (r[i] != i * 6) abort ();
/* map(alloc: r) + map(to: r): alloc and to on the same reference. */
for (int i = 0; i < N; i++) a[i] = i;
int sum = 0;
#pragma omp target map(alloc: r) map(to: r) map(tofrom: sum)
for (int i = 0; i < N; i++) sum += r[i];
if (sum != N * (N - 1) / 2) abort ();
}
/* Test pointer + array sections with enter/exit data using multiple map
clauses. */
static void
test_pointer_enter_exit ()
{
int *p = new int[N];
/* map(alloc) + map(to) on enter data. */
for (int i = 0; i < N; i++) p[i] = i;
#pragma omp target enter data map(alloc: p[0:N]) map(to: p[0:N])
int sum = 0;
#pragma omp target map(alloc: p[0:N]) map(tofrom: sum)
for (int i = 0; i < N; i++) sum += p[i];
if (sum != N * (N - 1) / 2) abort ();
#pragma omp target exit data map(delete: p[0:N])
/* map(release) + map(from) on exit data: copy back then release. */
for (int i = 0; i < N; i++) p[i] = i;
#pragma omp target enter data map(to: p[0:N])
#pragma omp target map(alloc: p[0:N])
for (int i = 0; i < N; i++) p[i] *= 3;
#pragma omp target exit data map(release: p[0:N]) map(from: p[0:N])
for (int i = 0; i < N; i++) if (p[i] != i * 3) abort ();
delete[] p;
}
int
main ()
{
test_pointer ();
test_reference ();
test_pointer_enter_exit ();
return 0;
}