[flang-commits] [flang] 79f7d3b - [flang][OpenMP] Add semantic checks for strict nesting inside `teams` construct.
Arnamoy Bhattacharyya via flang-commits
flang-commits at lists.llvm.org
Thu Apr 29 05:34:42 PDT 2021
Author: Arnamoy Bhattacharyya
Date: 2021-04-29T08:35:20-04:00
New Revision: 79f7d3b7b123faa80daf265277b32ac77998190f
URL: https://github.com/llvm/llvm-project/commit/79f7d3b7b123faa80daf265277b32ac77998190f
DIFF: https://github.com/llvm/llvm-project/commit/79f7d3b7b123faa80daf265277b32ac77998190f.diff
LOG: [flang][OpenMP] Add semantic checks for strict nesting inside `teams` construct.
Added:
flang/test/Semantics/omp-nested-distribute.f90
Modified:
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/check-omp-structure.h
flang/test/Semantics/omp-combined-constructs.f90
flang/test/Semantics/omp-device-constructs.f90
Removed:
################################################################################
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index c5d9aa2248392..23a29aecf11dd 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -182,7 +182,62 @@ bool OmpStructureChecker::HasInvalidWorksharingNesting(
return false;
}
-void OmpStructureChecker::Enter(const parser::OpenMPConstruct &) {
+void OmpStructureChecker::HasInvalidDistributeNesting(
+ const parser::OpenMPLoopConstruct &x) {
+ bool violation{false};
+
+ OmpDirectiveSet distributeSet{llvm::omp::Directive::OMPD_distribute,
+ llvm::omp::Directive::OMPD_distribute_parallel_do,
+ llvm::omp::Directive::OMPD_distribute_parallel_do_simd,
+ llvm::omp::Directive::OMPD_distribute_parallel_for,
+ llvm::omp::Directive::OMPD_distribute_parallel_for_simd,
+ llvm::omp::Directive::OMPD_distribute_simd};
+
+ const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t)};
+ const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
+ if (distributeSet.test(beginDir.v)) {
+ // `distribute` region has to be nested
+ if (!CurrentDirectiveIsNested()) {
+ violation = true;
+ } else {
+ // `distribute` region has to be strictly nested inside `teams`
+ if (!llvm::omp::teamSet.test(GetContextParent().directive)) {
+ violation = true;
+ }
+ }
+ }
+ if (violation) {
+ context_.Say(beginDir.source,
+ "`DISTRIBUTE` region has to be strictly nested inside `TEAMS` region."_err_en_US);
+ }
+}
+
+void OmpStructureChecker::HasInvalidTeamsNesting(
+ const llvm::omp::Directive &dir, const parser::CharBlock &source) {
+ OmpDirectiveSet allowedSet{llvm::omp::Directive::OMPD_parallel,
+ llvm::omp::Directive::OMPD_parallel_do,
+ llvm::omp::Directive::OMPD_parallel_do_simd,
+ llvm::omp::Directive::OMPD_parallel_for,
+ llvm::omp::Directive::OMPD_parallel_for_simd,
+ llvm::omp::Directive::OMPD_parallel_master,
+ llvm::omp::Directive::OMPD_parallel_master_taskloop,
+ llvm::omp::Directive::OMPD_parallel_master_taskloop_simd,
+ llvm::omp::Directive::OMPD_parallel_sections,
+ llvm::omp::Directive::OMPD_parallel_workshare,
+ llvm::omp::Directive::OMPD_distribute,
+ llvm::omp::Directive::OMPD_distribute_parallel_do,
+ llvm::omp::Directive::OMPD_distribute_parallel_do_simd,
+ llvm::omp::Directive::OMPD_distribute_parallel_for,
+ llvm::omp::Directive::OMPD_distribute_parallel_for_simd,
+ llvm::omp::Directive::OMPD_distribute_simd};
+
+ if (!allowedSet.test(dir)) {
+ context_.Say(source,
+ "Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region."_err_en_US);
+ }
+}
+
+void OmpStructureChecker::Enter(const parser::OpenMPConstruct &x) {
// 2.8.1 TODO: Simd Construct with Ordered Construct Nesting check
}
@@ -233,6 +288,11 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
CheckDoWhile(x);
CheckLoopItrVariableIsInt(x);
CheckCycleConstraints(x);
+ HasInvalidDistributeNesting(x);
+ if (CurrentDirectiveIsNested() &&
+ llvm::omp::teamSet.test(GetContextParent().directive)) {
+ HasInvalidTeamsNesting(beginDir.v, beginDir.source);
+ }
}
const parser::Name OmpStructureChecker::GetLoopIndex(
const parser::DoConstruct *x) {
@@ -366,8 +426,12 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
HasInvalidWorksharingNesting(
beginDir.source, {llvm::omp::Directive::OMPD_do});
}
- if (CurrentDirectiveIsNested())
+ if (CurrentDirectiveIsNested()) {
CheckIfDoOrderedClause(beginDir);
+ if (llvm::omp::teamSet.test(GetContextParent().directive)) {
+ HasInvalidTeamsNesting(beginDir.v, beginDir.source);
+ }
+ }
CheckNoBranching(block, beginDir.v, beginDir.source);
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 250ebbac548f8..ad3d4065f287c 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -71,6 +71,13 @@ static OmpDirectiveSet simdSet{Directive::OMPD_distribute_parallel_do_simd,
Directive::OMPD_taskloop_simd,
Directive::OMPD_teams_distribute_parallel_do_simd,
Directive::OMPD_teams_distribute_simd};
+static OmpDirectiveSet teamSet{Directive::OMPD_teams,
+ Directive::OMPD_teams_distribute,
+ Directive::OMPD_teams_distribute_parallel_do,
+ Directive::OMPD_teams_distribute_parallel_do_simd,
+ Directive::OMPD_teams_distribute_parallel_for,
+ Directive::OMPD_teams_distribute_parallel_for_simd,
+ Directive::OMPD_teams_distribute_simd};
static OmpDirectiveSet taskGeneratingSet{
OmpDirectiveSet{Directive::OMPD_task} | taskloopSet};
static OmpDirectiveSet nestedOrderedErrSet{Directive::OMPD_critical,
@@ -167,6 +174,9 @@ class OmpStructureChecker
bool HasInvalidWorksharingNesting(
const parser::CharBlock &, const OmpDirectiveSet &);
bool IsCloselyNestedRegion(const OmpDirectiveSet &set);
+ void HasInvalidTeamsNesting(
+ const llvm::omp::Directive &dir, const parser::CharBlock &source);
+ void HasInvalidDistributeNesting(const parser::OpenMPLoopConstruct &x);
// specific clause related
bool ScheduleModifierHasType(const parser::OmpScheduleClause &,
const parser::OmpScheduleModifierType::ModType &);
diff --git a/flang/test/Semantics/omp-combined-constructs.f90 b/flang/test/Semantics/omp-combined-constructs.f90
index fb30b50f3b549..48d4683f20feb 100644
--- a/flang/test/Semantics/omp-combined-constructs.f90
+++ b/flang/test/Semantics/omp-combined-constructs.f90
@@ -7,6 +7,7 @@ program main
real(8) :: a(256), b(256)
N = 256
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
!$omp distribute simd
do i = 1, N
a(i) = 3.14
diff --git a/flang/test/Semantics/omp-device-constructs.f90 b/flang/test/Semantics/omp-device-constructs.f90
index 5f6d7dde8ce56..1db7bfd19d73e 100644
--- a/flang/test/Semantics/omp-device-constructs.f90
+++ b/flang/test/Semantics/omp-device-constructs.f90
@@ -144,6 +144,7 @@ program main
!$omp target exit data map(to:a)
!$omp target
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
!$omp distribute
do i = 1, N
a = 3.14
@@ -152,6 +153,31 @@ program main
!$omp end target
!$omp target
+ !$omp teams
+ !$omp distribute
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute
+ !$omp end teams
+ !$omp end target
+
+ !$omp target
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !ERROR: At most one COLLAPSE clause can appear on the DISTRIBUTE directive
+ !$omp distribute collapse(2) collapse(3)
+ do i = 1, N
+ do j = 1, N
+ do k = 1, N
+ a = 3.14
+ enddo
+ enddo
+ enddo
+ !$omp end distribute
+ !$omp end target
+
+ !$omp target
+ !$omp teams
!ERROR: At most one COLLAPSE clause can appear on the DISTRIBUTE directive
!$omp distribute collapse(2) collapse(3)
do i = 1, N
@@ -162,9 +188,11 @@ program main
enddo
enddo
!$omp end distribute
+ !$omp end teams
!$omp end target
!$omp target
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
!$omp distribute dist_schedule(static, 2)
do i = 1, N
a = 3.14
@@ -173,6 +201,17 @@ program main
!$omp end target
!$omp target
+ !$omp teams
+ !$omp distribute dist_schedule(static, 2)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute
+ !$omp end teams
+ !$omp end target
+
+ !$omp target
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
!ERROR: At most one DIST_SCHEDULE clause can appear on the DISTRIBUTE directive
!$omp distribute dist_schedule(static, 2) dist_schedule(static, 3)
do i = 1, N
@@ -181,4 +220,15 @@ program main
!$omp end distribute
!$omp end target
+ !$omp target
+ !$omp teams
+ !ERROR: At most one DIST_SCHEDULE clause can appear on the DISTRIBUTE directive
+ !$omp distribute dist_schedule(static, 2) dist_schedule(static, 3)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute
+ !$omp end teams
+ !$omp end target
+
end program main
diff --git a/flang/test/Semantics/omp-nested-distribute.f90 b/flang/test/Semantics/omp-nested-distribute.f90
new file mode 100644
index 0000000000000..873dc6b554d19
--- /dev/null
+++ b/flang/test/Semantics/omp-nested-distribute.f90
@@ -0,0 +1,104 @@
+! RUN: %S/test_errors.sh %s %t %flang -fopenmp
+! Check OpenMP clause validity for the following directives:
+! 2.10 Device constructs
+program main
+
+ real(8) :: arrayA(256), arrayB(256)
+ integer :: N
+
+ arrayA = 1.414
+ arrayB = 3.14
+ N = 256
+
+ !$omp task
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute
+ !$omp end task
+
+ !$omp teams
+ do i = 1, N
+ !ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region.
+ !$omp task
+ do k = 1, N
+ a = 3.14
+ enddo
+ !$omp end task
+ enddo
+ !$omp end teams
+
+ !$omp teams
+ do i = 1, N
+ !$omp parallel
+ do k = 1, N
+ a = 3.14
+ enddo
+ !$omp end parallel
+ enddo
+ !$omp end teams
+
+ !$omp parallel
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute
+ !$omp end parallel
+
+ !$omp teams
+ !ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region.
+ !$omp target
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute
+ do i = 1, 10
+ j = j + 1
+ end do
+ !$omp end distribute
+ !$omp end target
+ !$omp end teams
+
+ !$omp teams
+ !$omp parallel
+ do k = 1,10
+ print *, "hello"
+ end do
+ !$omp end parallel
+ !$omp distribute firstprivate(a)
+ do i = 1, 10
+ j = j + 1
+ end do
+ !$omp end distribute
+ !$omp end teams
+
+ !$omp teams
+ !ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region.
+ !$omp task
+ do k = 1,10
+ print *, "hello"
+ end do
+ !$omp end task
+ !$omp distribute firstprivate(a)
+ do i = 1, 10
+ j = j + 1
+ end do
+ !$omp end distribute
+ !$omp end teams
+
+ !$omp task
+ !$omp parallel
+ do k = 1,10
+ print *, "hello"
+ end do
+ !$omp end parallel
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute firstprivate(a)
+ do i = 1, 10
+ j = j + 1
+ end do
+ !$omp end distribute
+ !$omp end task
+end program main
More information about the flang-commits
mailing list