xref: /llvm-project/offload/test/unified_shared_memory/close_modifier.c (revision 330d8983d25d08580fc1642fea48b2473f47a9da)
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