1 #include <omp.h>
2 #include <stdlib.h>
3
4 struct S
5 {
6 int a, b, c, d;
7 };
8 typedef struct S S;
9
10 int main (void)
11 {
12 int d = omp_get_default_device ();
13 int id = omp_get_initial_device ();
14
15 if (d < 0 || d >= omp_get_num_devices ())
16 d = id;
17
18 S s;
19
20 #pragma omp target enter data map (alloc: s)
21 #pragma omp target enter data map (alloc: s)
22
23 #pragma omp target exit data map (release: s.a)
24 #pragma omp target exit data map (release: s.b)
25
26 /* OpenMP 5.0 structure element mapping rules describe that elements of same
27 structure variable should allocate/deallocate in a uniform fashion, so
28 all elements of 's' should be removed together by above 'exit data's. */
29 if (d != id)
30 {
31 if (omp_target_is_present (&s, d))
32 abort ();
33 if (omp_target_is_present (&s.a, d))
34 abort ();
35 if (omp_target_is_present (&s.b, d))
36 abort ();
37 if (omp_target_is_present (&s.c, d))
38 abort ();
39 if (omp_target_is_present (&s.d, d))
40 abort ();
41 }
42
43 #pragma omp target enter data map (alloc: s.a, s.b)
44 #pragma omp target enter data map (alloc: s.a)
45 #pragma omp target enter data map (alloc: s.b)
46
47 #pragma omp target exit data map (release: s)
48 #pragma omp target exit data map (release: s)
49 #pragma omp target exit data map (release: s)
50
51 /* OpenMP 5.0 structure element mapping rules describe that elements of same
52 structure variable should allocate/deallocate in a uniform fashion, so
53 all elements of 's' should be removed together by above 'exit data's. */
54 if (d != id)
55 {
56 if (omp_target_is_present (&s, d))
57 abort ();
58 if (omp_target_is_present (&s.a, d))
59 abort ();
60 if (omp_target_is_present (&s.b, d))
61 abort ();
62 if (omp_target_is_present (&s.c, d))
63 abort ();
64 if (omp_target_is_present (&s.d, d))
65 abort ();
66 }
67
68 return 0;
69 }