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