| // 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; |
| } |