xref: /llvm-project/offload/test/unified_shared_memory/shared_update.c (revision 904b1a850536d273b0e11bd17a7ea642ba3b5bc4)
1*330d8983SJohannes Doerfert // RUN: %libomptarget-compile-run-and-check-generic
2*330d8983SJohannes Doerfert 
3*330d8983SJohannes Doerfert // REQUIRES: unified_shared_memory
4*330d8983SJohannes Doerfert 
5*330d8983SJohannes Doerfert // amdgpu runtime crash
6*330d8983SJohannes Doerfert // Fails on nvptx with error: an illegal memory access was encountered
7*330d8983SJohannes Doerfert // UNSUPPORTED: amdgcn-amd-amdhsa
8*330d8983SJohannes Doerfert // UNSUPPORTED: nvptx64-nvidia-cuda
9*330d8983SJohannes Doerfert // UNSUPPORTED: nvptx64-nvidia-cuda-LTO
10*330d8983SJohannes Doerfert 
11*330d8983SJohannes Doerfert #include <omp.h>
12*330d8983SJohannes Doerfert #include <stdio.h>
13*330d8983SJohannes Doerfert 
14*330d8983SJohannes Doerfert // End of definitions copied from OpenMP RTL.
15*330d8983SJohannes Doerfert // ---------------------------------------------------------------------------
16*330d8983SJohannes Doerfert 
17*330d8983SJohannes Doerfert #pragma omp requires unified_shared_memory
18*330d8983SJohannes Doerfert 
19*330d8983SJohannes Doerfert #define N 1024
20*330d8983SJohannes Doerfert 
main(int argc,char * argv[])21*330d8983SJohannes Doerfert int main(int argc, char *argv[]) {
22*330d8983SJohannes Doerfert   int fails;
23*330d8983SJohannes Doerfert   void *host_alloc, *device_alloc;
24*330d8983SJohannes Doerfert   void *host_data, *device_data;
25*330d8983SJohannes Doerfert   int *alloc = (int *)malloc(N * sizeof(int));
26*330d8983SJohannes Doerfert   int data[N];
27*330d8983SJohannes Doerfert 
28*330d8983SJohannes Doerfert   for (int i = 0; i < N; ++i) {
29*330d8983SJohannes Doerfert     alloc[i] = 10;
30*330d8983SJohannes Doerfert     data[i] = 1;
31*330d8983SJohannes Doerfert   }
32*330d8983SJohannes Doerfert 
33*330d8983SJohannes Doerfert   host_data = &data[0];
34*330d8983SJohannes Doerfert   host_alloc = &alloc[0];
35*330d8983SJohannes Doerfert 
36*330d8983SJohannes Doerfert // implicit mapping of data
37*330d8983SJohannes Doerfert #pragma omp target map(tofrom : device_data, device_alloc)
38*330d8983SJohannes Doerfert   {
39*330d8983SJohannes Doerfert     device_data = &data[0];
40*330d8983SJohannes Doerfert     device_alloc = &alloc[0];
41*330d8983SJohannes Doerfert 
42*330d8983SJohannes Doerfert     for (int i = 0; i < N; i++) {
43*330d8983SJohannes Doerfert       alloc[i] += 1;
44*330d8983SJohannes Doerfert       data[i] += 1;
45*330d8983SJohannes Doerfert     }
46*330d8983SJohannes Doerfert   }
47*330d8983SJohannes Doerfert 
48*330d8983SJohannes Doerfert   // CHECK: Address of alloc on device matches host address.
49*330d8983SJohannes Doerfert   if (device_alloc == host_alloc)
50*330d8983SJohannes Doerfert     printf("Address of alloc on device matches host address.\n");
51*330d8983SJohannes Doerfert 
52*330d8983SJohannes Doerfert   // CHECK: Address of data on device matches host address.
53*330d8983SJohannes Doerfert   if (device_data == host_data)
54*330d8983SJohannes Doerfert     printf("Address of data on device matches host address.\n");
55*330d8983SJohannes Doerfert 
56*330d8983SJohannes Doerfert   // On the host, check that the arrays have been updated.
57*330d8983SJohannes Doerfert   // CHECK: Alloc device values updated: Succeeded
58*330d8983SJohannes Doerfert   fails = 0;
59*330d8983SJohannes Doerfert   for (int i = 0; i < N; i++) {
60*330d8983SJohannes Doerfert     if (alloc[i] != 11)
61*330d8983SJohannes Doerfert       fails++;
62*330d8983SJohannes Doerfert   }
63*330d8983SJohannes Doerfert   printf("Alloc device values updated: %s\n",
64*330d8983SJohannes Doerfert          (fails == 0) ? "Succeeded" : "Failed");
65*330d8983SJohannes Doerfert 
66*330d8983SJohannes Doerfert   // CHECK: Data device values updated: Succeeded
67*330d8983SJohannes Doerfert   fails = 0;
68*330d8983SJohannes Doerfert   for (int i = 0; i < N; i++) {
69*330d8983SJohannes Doerfert     if (data[i] != 2)
70*330d8983SJohannes Doerfert       fails++;
71*330d8983SJohannes Doerfert   }
72*330d8983SJohannes Doerfert   printf("Data device values updated: %s\n",
73*330d8983SJohannes Doerfert          (fails == 0) ? "Succeeded" : "Failed");
74*330d8983SJohannes Doerfert 
75*330d8983SJohannes Doerfert   //
76*330d8983SJohannes Doerfert   // Test that updates on the host snd on the device are both visible.
77*330d8983SJohannes Doerfert   //
78*330d8983SJohannes Doerfert 
79*330d8983SJohannes Doerfert   // Update on the host.
80*330d8983SJohannes Doerfert   for (int i = 0; i < N; ++i) {
81*330d8983SJohannes Doerfert     alloc[i] += 1;
82*330d8983SJohannes Doerfert     data[i] += 1;
83*330d8983SJohannes Doerfert   }
84*330d8983SJohannes Doerfert 
85*330d8983SJohannes Doerfert #pragma omp target
86*330d8983SJohannes Doerfert   {
87*330d8983SJohannes Doerfert     // CHECK: Alloc host values updated: Succeeded
88*330d8983SJohannes Doerfert     fails = 0;
89*330d8983SJohannes Doerfert     for (int i = 0; i < N; i++) {
90*330d8983SJohannes Doerfert       if (alloc[i] != 12)
91*330d8983SJohannes Doerfert         fails++;
92*330d8983SJohannes Doerfert     }
93*330d8983SJohannes Doerfert     printf("Alloc host values updated: %s\n",
94*330d8983SJohannes Doerfert            (fails == 0) ? "Succeeded" : "Failed");
95*330d8983SJohannes Doerfert     // CHECK: Data host values updated: Succeeded
96*330d8983SJohannes Doerfert     fails = 0;
97*330d8983SJohannes Doerfert     for (int i = 0; i < N; i++) {
98*330d8983SJohannes Doerfert       if (data[i] != 3)
99*330d8983SJohannes Doerfert         fails++;
100*330d8983SJohannes Doerfert     }
101*330d8983SJohannes Doerfert     printf("Data host values updated: %s\n",
102*330d8983SJohannes Doerfert            (fails == 0) ? "Succeeded" : "Failed");
103*330d8983SJohannes Doerfert   }
104*330d8983SJohannes Doerfert 
105*330d8983SJohannes Doerfert   free(alloc);
106*330d8983SJohannes Doerfert 
107*330d8983SJohannes Doerfert   printf("Done!\n");
108*330d8983SJohannes Doerfert 
109*330d8983SJohannes Doerfert   return 0;
110*330d8983SJohannes Doerfert }
111