1*330d8983SJohannes Doerfert // RUN: %libomptarget-compile-run-and-check-generic
2*330d8983SJohannes Doerfert
3*330d8983SJohannes Doerfert // REQUIRES: unified_shared_memory
4*330d8983SJohannes Doerfert // UNSUPPORTED: clang-6, clang-7, clang-8, clang-9
5*330d8983SJohannes Doerfert
6*330d8983SJohannes Doerfert // amdgpu runtime crash
7*330d8983SJohannes Doerfert // Fails on nvptx with error: an illegal memory access was encountered
8*330d8983SJohannes Doerfert // UNSUPPORTED: amdgcn-amd-amdhsa
9*330d8983SJohannes Doerfert // UNSUPPORTED: nvptx64-nvidia-cuda
10*330d8983SJohannes Doerfert // UNSUPPORTED: nvptx64-nvidia-cuda-LTO
11*330d8983SJohannes Doerfert
12*330d8983SJohannes Doerfert #include <omp.h>
13*330d8983SJohannes Doerfert #include <stdio.h>
14*330d8983SJohannes Doerfert
15*330d8983SJohannes Doerfert #pragma omp requires unified_shared_memory
16*330d8983SJohannes Doerfert
17*330d8983SJohannes Doerfert #define N 1024
18*330d8983SJohannes Doerfert
main(int argc,char * argv[])19*330d8983SJohannes Doerfert int main(int argc, char *argv[]) {
20*330d8983SJohannes Doerfert int fails;
21*330d8983SJohannes Doerfert void *host_alloc, *device_alloc;
22*330d8983SJohannes Doerfert void *host_data, *device_data;
23*330d8983SJohannes Doerfert int *alloc = (int *)malloc(N * sizeof(int));
24*330d8983SJohannes Doerfert int data[N];
25*330d8983SJohannes Doerfert
26*330d8983SJohannes Doerfert for (int i = 0; i < N; ++i) {
27*330d8983SJohannes Doerfert alloc[i] = 10;
28*330d8983SJohannes Doerfert data[i] = 1;
29*330d8983SJohannes Doerfert }
30*330d8983SJohannes Doerfert
31*330d8983SJohannes Doerfert host_data = &data[0];
32*330d8983SJohannes Doerfert host_alloc = &alloc[0];
33*330d8983SJohannes Doerfert
34*330d8983SJohannes Doerfert //
35*330d8983SJohannes Doerfert // Test that updates on the device are not visible to host
36*330d8983SJohannes Doerfert // when only a TO mapping is used.
37*330d8983SJohannes Doerfert //
38*330d8983SJohannes Doerfert #pragma omp target map(tofrom : device_data, device_alloc) \
39*330d8983SJohannes Doerfert map(close, to : alloc[ : N], data[ : N])
40*330d8983SJohannes Doerfert {
41*330d8983SJohannes Doerfert device_data = &data[0];
42*330d8983SJohannes Doerfert device_alloc = &alloc[0];
43*330d8983SJohannes Doerfert
44*330d8983SJohannes Doerfert for (int i = 0; i < N; i++) {
45*330d8983SJohannes Doerfert alloc[i] += 1;
46*330d8983SJohannes Doerfert data[i] += 1;
47*330d8983SJohannes Doerfert }
48*330d8983SJohannes Doerfert }
49*330d8983SJohannes Doerfert
50*330d8983SJohannes Doerfert // CHECK: Address of alloc on device different from host address.
51*330d8983SJohannes Doerfert if (device_alloc != host_alloc)
52*330d8983SJohannes Doerfert printf("Address of alloc on device different from host address.\n");
53*330d8983SJohannes Doerfert
54*330d8983SJohannes Doerfert // CHECK: Address of data on device different from host address.
55*330d8983SJohannes Doerfert if (device_data != host_data)
56*330d8983SJohannes Doerfert printf("Address of data on device different from host address.\n");
57*330d8983SJohannes Doerfert
58*330d8983SJohannes Doerfert // On the host, check that the arrays have been updated.
59*330d8983SJohannes Doerfert // CHECK: Alloc host values not updated: Succeeded
60*330d8983SJohannes Doerfert fails = 0;
61*330d8983SJohannes Doerfert for (int i = 0; i < N; i++) {
62*330d8983SJohannes Doerfert if (alloc[i] != 10)
63*330d8983SJohannes Doerfert fails++;
64*330d8983SJohannes Doerfert }
65*330d8983SJohannes Doerfert printf("Alloc host values not updated: %s\n",
66*330d8983SJohannes Doerfert (fails == 0) ? "Succeeded" : "Failed");
67*330d8983SJohannes Doerfert
68*330d8983SJohannes Doerfert // CHECK: Data host values not updated: Succeeded
69*330d8983SJohannes Doerfert fails = 0;
70*330d8983SJohannes Doerfert for (int i = 0; i < N; i++) {
71*330d8983SJohannes Doerfert if (data[i] != 1)
72*330d8983SJohannes Doerfert fails++;
73*330d8983SJohannes Doerfert }
74*330d8983SJohannes Doerfert printf("Data host values not updated: %s\n",
75*330d8983SJohannes Doerfert (fails == 0) ? "Succeeded" : "Failed");
76*330d8983SJohannes Doerfert
77*330d8983SJohannes Doerfert //
78*330d8983SJohannes Doerfert // Test that updates on the device are visible on host
79*330d8983SJohannes Doerfert // when a from is used.
80*330d8983SJohannes Doerfert //
81*330d8983SJohannes Doerfert
82*330d8983SJohannes Doerfert for (int i = 0; i < N; i++) {
83*330d8983SJohannes Doerfert alloc[i] += 1;
84*330d8983SJohannes Doerfert data[i] += 1;
85*330d8983SJohannes Doerfert }
86*330d8983SJohannes Doerfert
87*330d8983SJohannes Doerfert #pragma omp target map(close, tofrom : alloc[ : N], data[ : N])
88*330d8983SJohannes Doerfert {
89*330d8983SJohannes Doerfert // CHECK: Alloc device values are correct: Succeeded
90*330d8983SJohannes Doerfert fails = 0;
91*330d8983SJohannes Doerfert for (int i = 0; i < N; i++) {
92*330d8983SJohannes Doerfert if (alloc[i] != 11)
93*330d8983SJohannes Doerfert fails++;
94*330d8983SJohannes Doerfert }
95*330d8983SJohannes Doerfert printf("Alloc device values are correct: %s\n",
96*330d8983SJohannes Doerfert (fails == 0) ? "Succeeded" : "Failed");
97*330d8983SJohannes Doerfert // CHECK: Data device values are correct: Succeeded
98*330d8983SJohannes Doerfert fails = 0;
99*330d8983SJohannes Doerfert for (int i = 0; i < N; i++) {
100*330d8983SJohannes Doerfert if (data[i] != 2)
101*330d8983SJohannes Doerfert fails++;
102*330d8983SJohannes Doerfert }
103*330d8983SJohannes Doerfert printf("Data device values are correct: %s\n",
104*330d8983SJohannes Doerfert (fails == 0) ? "Succeeded" : "Failed");
105*330d8983SJohannes Doerfert
106*330d8983SJohannes Doerfert // Update values on the device
107*330d8983SJohannes Doerfert for (int i = 0; i < N; i++) {
108*330d8983SJohannes Doerfert alloc[i] += 1;
109*330d8983SJohannes Doerfert data[i] += 1;
110*330d8983SJohannes Doerfert }
111*330d8983SJohannes Doerfert }
112*330d8983SJohannes Doerfert
113*330d8983SJohannes Doerfert // CHECK: Alloc host values updated: Succeeded
114*330d8983SJohannes Doerfert fails = 0;
115*330d8983SJohannes Doerfert for (int i = 0; i < N; i++) {
116*330d8983SJohannes Doerfert if (alloc[i] != 12)
117*330d8983SJohannes Doerfert fails++;
118*330d8983SJohannes Doerfert }
119*330d8983SJohannes Doerfert printf("Alloc host values updated: %s\n",
120*330d8983SJohannes Doerfert (fails == 0) ? "Succeeded" : "Failed");
121*330d8983SJohannes Doerfert
122*330d8983SJohannes Doerfert // CHECK: Data host values updated: Succeeded
123*330d8983SJohannes Doerfert fails = 0;
124*330d8983SJohannes Doerfert for (int i = 0; i < N; i++) {
125*330d8983SJohannes Doerfert if (data[i] != 3)
126*330d8983SJohannes Doerfert fails++;
127*330d8983SJohannes Doerfert }
128*330d8983SJohannes Doerfert printf("Data host values updated: %s\n",
129*330d8983SJohannes Doerfert (fails == 0) ? "Succeeded" : "Failed");
130*330d8983SJohannes Doerfert
131*330d8983SJohannes Doerfert free(alloc);
132*330d8983SJohannes Doerfert
133*330d8983SJohannes Doerfert // CHECK: Done!
134*330d8983SJohannes Doerfert printf("Done!\n");
135*330d8983SJohannes Doerfert
136*330d8983SJohannes Doerfert return 0;
137*330d8983SJohannes Doerfert }
138