You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
OpenMP has restrictions on directives allowed to be strictly nested
inside a
construct with the order(concurrent) clause specified.
- OpenMP 5.0, 5.1, and 5.2 allows: 'loop', 'parallel', 'simd', and
combined directives starting with 'parallel'.
- OpenMP 6.0 allows: the above directives plus 'atomic' and
all loop-transformation directives.
Furthermore, a region that corresponds to a construct with
order(concurrent)
specified may not contain calls to the OpenMP runtime API.
This PR fixes the following issues in the current implementation:
With -fopenmp-version=50: none of the nesting restrictions above were
enforced
With -fopenmp-version=60:
1. Clang did not reject OpenMP runtime APIs encountered in the region.
2. Clang erroneously rejected combined directives starting with
parallel.
---------
Co-authored-by: Zahira Ammarguellat <[email protected]>
// Constructs strictly nestable in a construct with order(concurrent) specified vary by OpenMP version:
12
+
// OMP5.0,5.1,5.2: loop, parallel, simd, and combined constructs with parallel as the first component.
13
+
// OMP6.0: in addition to the ones allowed in OMP5.x, also atomic and all loop-transformation constructs.
14
+
11
15
externintomp_get_num_threads (void);
12
16
13
17
intmain(int argc, char **argv) {
14
18
int A = 0;
15
19
#pragma omp parallel for order(concurrent)
16
20
for (int i = 0; i < 10; ++i)
17
-
omp_get_num_threads(); // omp51-error {{calls to OpenMP runtime API are not allowed within a region that corresponds to a construct with an order clause that specifies concurrent}}
21
+
omp_get_num_threads(); //omp50-error {{calls to OpenMP runtime API are not allowed within a region that corresponds to a construct with an order clause that specifies concurrent}} omp51-error {{calls to OpenMP runtime API are not allowed within a region that corresponds to a construct with an order clause that specifies concurrent}} omp60-error {{calls to OpenMP runtime API are not allowed within a region that corresponds to a construct with an order clause that specifies concurrent}}
18
22
19
23
#pragma omp parallel for order(reproducible:concurrent) // omp50-error {{expected 'concurrent' in OpenMP clause 'order'}}
20
24
for (int i = 0; i < 10; ++i)
21
-
omp_get_num_threads(); // omp51-error {{calls to OpenMP runtime API are not allowed within a region that corresponds to a construct with an order clause that specifies concurrent}}
25
+
omp_get_num_threads(); // omp51-error {{calls to OpenMP runtime API are not allowed within a region that corresponds to a construct with an order clause that specifies concurrent}} omp60-error {{calls to OpenMP runtime API are not allowed within a region that corresponds to a construct with an order clause that specifies concurrent}}
22
26
23
27
#pragma omp parallel for order(unconstrained:concurrent) // omp50-error {{expected 'concurrent' in OpenMP clause 'order'}}
24
28
for (int i = 0; i < 10; ++i)
25
-
omp_get_num_threads(); // omp51-error {{calls to OpenMP runtime API are not allowed within a region that corresponds to a construct with an order clause that specifies concurrent}}
29
+
omp_get_num_threads(); // omp51-error {{calls to OpenMP runtime API are not allowed within a region that corresponds to a construct with an order clause that specifies concurrent}} omp60-error {{calls to OpenMP runtime API are not allowed within a region that corresponds to a construct with an order clause that specifies concurrent}}
26
30
27
31
#pragma omp parallel for order(concurrent)
28
32
for (int i = 0; i < 10; ++i) {
29
33
for (int j = 0; j < 10; ++j) {
30
-
omp_get_num_threads(); // omp51-error {{calls to OpenMP runtime API are not allowed within a region that corresponds to a construct with an order clause that specifies concurrent}}
34
+
omp_get_num_threads(); //omp50-error {{calls to OpenMP runtime API are not allowed within a region that corresponds to a construct with an order clause that specifies concurrent}} omp51-error {{calls to OpenMP runtime API are not allowed within a region that corresponds to a construct with an order clause that specifies concurrent}} omp60-error {{calls to OpenMP runtime API are not allowed within a region that corresponds to a construct with an order clause that specifies concurrent}}
31
35
}
32
36
}
33
37
38
+
// nested atomic: OK in OMP6.0 but not in OMP5.x
34
39
#pragma omp parallel for order(concurrent)
35
40
for (int i = 0; i < 10; ++i) {
36
-
#pragma omp atomic //omp51-error {{construct 'atomic' not allowed in a region associated with a directive with 'order' clause}}
41
+
#pragma omp atomic //omp50-error {{construct 'atomic' not allowed in a region associated with a directive with 'order' clause}} omp51-error {{construct 'atomic' not allowed in a region associated with a directive with 'order' clause}}
37
42
A++;
38
43
}
39
44
45
+
// nested loop-transformation construct: OK in OMP6.0 but not in OMP5.x
46
+
#pragma omp parallel for order(concurrent)
47
+
for (int i = 0; i < 10; ++i) {
48
+
#pragma omp unroll //omp50-error {{construct 'unroll' not allowed in a region associated with a directive with 'order' clause}} omp51-error {{construct 'unroll' not allowed in a region associated with a directive with 'order' clause}}
49
+
for (int j = 0; j < 10; ++j);
50
+
}
51
+
40
52
#pragma omp parallel for order(reproducible: concurrent) // omp50-error {{expected 'concurrent' in OpenMP clause 'order'}}
41
53
for (int i = 0; i < 10; ++i) {
42
54
#pragma omp target //omp51-error {{construct 'target' not allowed in a region associated with a directive with 'order' clause}} omp60-error {{construct 'target' not allowed in a region associated with a directive with 'order' clause}}
@@ -51,47 +63,47 @@ int main(int argc, char **argv) {
51
63
52
64
#pragma omp loop bind(parallel) order(concurrent)
53
65
for (int i = 0; i < 10; ++i) {
54
-
#pragma omp parallel for//omp60-error {{construct 'parallel for' not allowed in a region associated with a directive with 'order' clause}}
66
+
#pragma omp parallel for
55
67
for (int j = 0; j < 10; ++j) {
56
68
A += j;
57
69
}
58
70
}
59
71
60
72
#pragma omp distribute order(concurrent)
61
73
for (int i = 0; i < 10; ++i) {
62
-
#pragma omp parallel for simd//omp60-error {{construct 'parallel for simd' not allowed in a region associated with a directive with 'order' clause}}
74
+
#pragma omp parallel for simd
63
75
for (int j = 0; j < 10; ++j) {
64
76
A += j;
65
77
}
66
78
}
67
79
68
80
#pragma omp for order(concurrent)
69
81
for (int i = 0; i < 10; ++i) {
70
-
#pragma omp parallel master//omp60-error {{construct 'parallel master' not allowed in a region associated with a directive with 'order' clause}}
82
+
#pragma omp parallel master
71
83
for (int j = 0; j < 10; ++j) {
72
84
A += j;
73
85
}
74
86
}
75
87
76
88
#pragma omp for order(concurrent)
77
89
for (int i = 0; i < 10; ++i) {
78
-
#pragma omp parallel master taskloop//omp60-error {{construct 'parallel master taskloop' not allowed in a region associated with a directive with 'order' clause}}
90
+
#pragma omp parallel master taskloop
79
91
for (int j = 0; j < 10; ++j) {
80
92
A += j;
81
93
}
82
94
}
83
95
84
96
#pragma omp for order(concurrent)
85
97
for (int i = 0; i < 10; ++i) {
86
-
#pragma omp parallel master taskloop simd//omp60-error {{construct 'parallel master taskloop simd' not allowed in a region associated with a directive with 'order' clause}}
98
+
#pragma omp parallel master taskloop simd
87
99
for (int j = 0; j < 10; ++j) {
88
100
A += j;
89
101
}
90
102
}
91
103
92
104
#pragma omp for order(concurrent)
93
105
for (int i = 0; i < 10; ++i) {
94
-
#pragma omp parallel sections//omp60-error {{construct 'parallel sections' not allowed in a region associated with a directive with 'order' clause}}
0 commit comments