[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