1 | // RUN: %libomp-compile-and-run |
2 | |
3 | #include <stdio.h> |
4 | #include <stdlib.h> |
5 | #include <omp.h> |
6 | |
7 | int a; |
8 | |
9 | void inc_a() { |
10 | #pragma omp atomic |
11 | a++; |
12 | } |
13 | |
14 | void root_team_detached() { |
15 | a = 0; |
16 | omp_event_handle_t ev; |
17 | #pragma omp task detach(ev) |
18 | inc_a(); |
19 | omp_fulfill_event(ev); |
20 | if (a != 1) { |
21 | fprintf(stderr, format: "error: root_team_detached(): a != 1\n" ); |
22 | exit(EXIT_FAILURE); |
23 | } |
24 | } |
25 | |
26 | void root_team_hidden_helpers() { |
27 | a = 0; |
28 | #pragma omp target nowait |
29 | inc_a(); |
30 | |
31 | #pragma omp taskwait |
32 | |
33 | if (a != 1) { |
34 | fprintf(stderr, format: "error: root_team_hidden_helpers(): a != 1\n" ); |
35 | exit(EXIT_FAILURE); |
36 | } |
37 | } |
38 | |
39 | void parallel_detached(int nth1) { |
40 | a = 0; |
41 | omp_event_handle_t *evs = |
42 | (omp_event_handle_t *)malloc(sizeof(omp_event_handle_t) * nth1); |
43 | #pragma omp parallel num_threads(nth1) |
44 | { |
45 | int tid = omp_get_thread_num(); |
46 | omp_event_handle_t e = evs[tid]; |
47 | #pragma omp task detach(e) |
48 | inc_a(); |
49 | omp_fulfill_event(e); |
50 | } |
51 | free(ptr: evs); |
52 | if (a != nth1) { |
53 | fprintf(stderr, format: "error: parallel_detached(): a (%d) != %d\n" , a, nth1); |
54 | exit(EXIT_FAILURE); |
55 | } |
56 | } |
57 | |
58 | void parallel_hidden_helpers(int nth1) { |
59 | a = 0; |
60 | #pragma omp parallel num_threads(nth1) |
61 | { |
62 | #pragma omp target nowait |
63 | inc_a(); |
64 | } |
65 | if (a != nth1) { |
66 | fprintf(stderr, format: "error: parallel_hidden_helpers(): a (%d) != %d\n" , a, |
67 | nth1); |
68 | exit(EXIT_FAILURE); |
69 | } |
70 | } |
71 | |
72 | void nested_parallel_detached(int nth1, int nth2) { |
73 | a = 0; |
74 | omp_event_handle_t **evs = |
75 | (omp_event_handle_t **)malloc(sizeof(omp_event_handle_t *) * nth1); |
76 | #pragma omp parallel num_threads(nth1) |
77 | { |
78 | int tid = omp_get_thread_num(); |
79 | evs[tid] = (omp_event_handle_t *)malloc(sizeof(omp_event_handle_t) * nth2); |
80 | #pragma omp parallel num_threads(nth2) shared(tid) |
81 | { |
82 | int tid2 = omp_get_thread_num(); |
83 | omp_event_handle_t e = evs[tid][tid2]; |
84 | #pragma omp task detach(e) |
85 | inc_a(); |
86 | omp_fulfill_event(e); |
87 | } |
88 | free(evs[tid]); |
89 | } |
90 | free(ptr: evs); |
91 | if (a != nth1 * nth2) { |
92 | fprintf(stderr, format: "error: nested_parallel_detached(): a (%d) != %d * %d\n" , a, |
93 | nth1, nth2); |
94 | exit(EXIT_FAILURE); |
95 | } |
96 | } |
97 | |
98 | void nested_parallel_hidden_helpers(int nth1, int nth2) { |
99 | a = 0; |
100 | #pragma omp parallel num_threads(nth1) |
101 | { |
102 | #pragma omp parallel num_threads(nth2) |
103 | { |
104 | #pragma omp target nowait |
105 | inc_a(); |
106 | } |
107 | } |
108 | if (a != nth1 * nth2) { |
109 | fprintf(stderr, |
110 | format: "error: nested_parallel_hidden_helpers(): a (%d) != %d * %d\n" , a, |
111 | nth1, nth2); |
112 | exit(EXIT_FAILURE); |
113 | } |
114 | } |
115 | |
116 | int main() { |
117 | int i, nth1, nth2; |
118 | |
119 | omp_set_max_active_levels(2); |
120 | omp_set_dynamic(0); |
121 | |
122 | for (i = 0; i < 10; ++i) |
123 | root_team_detached(); |
124 | |
125 | for (i = 0; i < 10; ++i) |
126 | root_team_hidden_helpers(); |
127 | |
128 | for (i = 0; i < 10; ++i) |
129 | for (nth1 = 1; nth1 <= 4; ++nth1) |
130 | parallel_detached(nth1); |
131 | |
132 | for (i = 0; i < 10; ++i) |
133 | for (nth1 = 1; nth1 <= 4; ++nth1) |
134 | parallel_hidden_helpers(nth1); |
135 | |
136 | for (i = 0; i < 10; ++i) |
137 | for (nth1 = 1; nth1 <= 4; ++nth1) |
138 | for (nth2 = 1; nth2 <= 4; ++nth2) |
139 | nested_parallel_detached(nth1, nth2); |
140 | |
141 | for (i = 0; i < 10; ++i) |
142 | for (nth1 = 1; nth1 <= 4; ++nth1) |
143 | for (nth2 = 1; nth2 <= 4; ++nth2) |
144 | nested_parallel_hidden_helpers(nth1, nth2); |
145 | |
146 | return 0; |
147 | } |
148 | |