[flang-commits] [flang] 70894c8 - [flang][OpenMP] Add semantic checks for cancellation nesting
Arnamoy Bhattacharyya via flang-commits
flang-commits at lists.llvm.org
Fri Aug 13 07:11:27 PDT 2021
Author: Peixin Qiao
Date: 2021-08-13T10:11:39-04:00
New Revision: 70894c8dd14d35ba8bc6ab317d76e0b325c3f7f0
URL: https://github.com/llvm/llvm-project/commit/70894c8dd14d35ba8bc6ab317d76e0b325c3f7f0
DIFF: https://github.com/llvm/llvm-project/commit/70894c8dd14d35ba8bc6ab317d76e0b325c3f7f0.diff
LOG: [flang][OpenMP] Add semantic checks for cancellation nesting
This patch implements the following semantic checks for cancellation constructs:
```
OpenMP Version 5.0 Section 2.18.1: CANCEL construct restriction:
If construct-type-clause is taskgroup, the cancel construct must be
closely nested inside a task or a taskloop construct and the cancel
region must be closely nested inside a taskgroup region. If
construct-type-clause is sections, the cancel construct must be closely
nested inside a sections or section construct. Otherwise, the cancel
construct must be closely nested inside an OpenMP construct that matches
the type specified in construct-type-clause of the cancel construct.
OpenMP Version 5.0 Section 2.18.2: CANCELLATION POINT restriction:
A cancellation point construct for which construct-type-clause is
taskgroup must be closely nested inside a task or taskloop construct,
and the cancellation point region must be closely nested inside a
taskgroup region. A cancellation point construct for which
construct-type-clause is sections must be closely nested inside a
sections or section construct. A cancellation point construct for which
construct-type-clause is neither sections nor taskgroup must be closely
nested inside an OpenMP construct that matches the type specified in
construct-type-clause.
```
Also add test cases for the check.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D106538
Added:
flang/test/Semantics/omp-nested-cancel.f90
flang/test/Semantics/omp-nested-cancellation-point.f90
Modified:
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/check-omp-structure.h
flang/test/Semantics/omp-clause-validity01.f90
Removed:
################################################################################
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index e8e5ca991f14f..34499e6d5f975 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -846,7 +846,9 @@ void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &x) {
void OmpStructureChecker::Enter(const parser::OpenMPCancelConstruct &x) {
const auto &dir{std::get<parser::Verbatim>(x.t)};
+ const auto &type{std::get<parser::OmpCancelType>(x.t)};
PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_cancel);
+ CheckCancellationNest(dir.source, type.v);
}
void OmpStructureChecker::Leave(const parser::OpenMPCancelConstruct &) {
@@ -867,8 +869,10 @@ void OmpStructureChecker::Leave(const parser::OpenMPCriticalConstruct &) {
void OmpStructureChecker::Enter(
const parser::OpenMPCancellationPointConstruct &x) {
const auto &dir{std::get<parser::Verbatim>(x.t)};
+ const auto &type{std::get<parser::OmpCancelType>(x.t)};
PushContextAndClauseSets(
dir.source, llvm::omp::Directive::OMPD_cancellation_point);
+ CheckCancellationNest(dir.source, type.v);
}
void OmpStructureChecker::Leave(
@@ -876,6 +880,133 @@ void OmpStructureChecker::Leave(
dirContext_.pop_back();
}
+void OmpStructureChecker::CheckCancellationNest(
+ const parser::CharBlock &source, const parser::OmpCancelType::Type &type) {
+ if (CurrentDirectiveIsNested()) {
+ // If construct-type-clause is taskgroup, the cancellation construct must be
+ // closely nested inside a task or a taskloop construct and the cancellation
+ // region must be closely nested inside a taskgroup region. If
+ // construct-type-clause is sections, the cancellation construct must be
+ // closely nested inside a sections or section construct. Otherwise, the
+ // cancellation construct must be closely nested inside an OpenMP construct
+ // that matches the type specified in construct-type-clause of the
+ // cancellation construct.
+
+ OmpDirectiveSet allowedTaskgroupSet{
+ llvm::omp::Directive::OMPD_task, llvm::omp::Directive::OMPD_taskloop};
+ OmpDirectiveSet allowedSectionsSet{llvm::omp::Directive::OMPD_sections,
+ llvm::omp::Directive::OMPD_parallel_sections};
+ OmpDirectiveSet allowedDoSet{llvm::omp::Directive::OMPD_do,
+ llvm::omp::Directive::OMPD_distribute_parallel_do,
+ llvm::omp::Directive::OMPD_parallel_do,
+ llvm::omp::Directive::OMPD_target_parallel_do,
+ llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do,
+ llvm::omp::Directive::OMPD_teams_distribute_parallel_do};
+ OmpDirectiveSet allowedParallelSet{llvm::omp::Directive::OMPD_parallel,
+ llvm::omp::Directive::OMPD_target_parallel};
+
+ bool eligibleCancellation{false};
+ switch (type) {
+ case parser::OmpCancelType::Type::Taskgroup:
+ if (allowedTaskgroupSet.test(GetContextParent().directive)) {
+ eligibleCancellation = true;
+ if (dirContext_.size() >= 3) {
+ // Check if the cancellation region is closely nested inside a
+ // taskgroup region when there are more than two levels of directives
+ // in the directive context stack.
+ if (GetContextParent().directive == llvm::omp::Directive::OMPD_task ||
+ FindClauseParent(llvm::omp::Clause::OMPC_nogroup)) {
+ for (int i = dirContext_.size() - 3; i >= 0; i--) {
+ if (dirContext_[i].directive ==
+ llvm::omp::Directive::OMPD_taskgroup) {
+ break;
+ }
+ if (allowedParallelSet.test(dirContext_[i].directive)) {
+ eligibleCancellation = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (!eligibleCancellation) {
+ context_.Say(source,
+ "With %s clause, %s construct must be closely nested inside TASK "
+ "or TASKLOOP construct and %s region must be closely nested inside "
+ "TASKGROUP region"_err_en_US,
+ parser::ToUpperCaseLetters(
+ parser::OmpCancelType::EnumToString(type)),
+ ContextDirectiveAsFortran(), ContextDirectiveAsFortran());
+ }
+ return;
+ case parser::OmpCancelType::Type::Sections:
+ if (allowedSectionsSet.test(GetContextParent().directive)) {
+ eligibleCancellation = true;
+ }
+ break;
+ case Fortran::parser::OmpCancelType::Type::Do:
+ if (allowedDoSet.test(GetContextParent().directive)) {
+ eligibleCancellation = true;
+ }
+ break;
+ case parser::OmpCancelType::Type::Parallel:
+ if (allowedParallelSet.test(GetContextParent().directive)) {
+ eligibleCancellation = true;
+ }
+ break;
+ default:
+ break;
+ }
+ if (!eligibleCancellation) {
+ context_.Say(source,
+ "With %s clause, %s construct cannot be closely nested inside %s "
+ "construct"_err_en_US,
+ parser::ToUpperCaseLetters(parser::OmpCancelType::EnumToString(type)),
+ ContextDirectiveAsFortran(),
+ parser::ToUpperCaseLetters(
+ getDirectiveName(GetContextParent().directive).str()));
+ }
+ } else {
+ // The cancellation directive cannot be orphaned.
+ switch (type) {
+ case parser::OmpCancelType::Type::Taskgroup:
+ context_.Say(source,
+ "%s %s directive is not closely nested inside "
+ "TASK or TASKLOOP"_err_en_US,
+ ContextDirectiveAsFortran(),
+ parser::ToUpperCaseLetters(
+ parser::OmpCancelType::EnumToString(type)));
+ break;
+ case parser::OmpCancelType::Type::Sections:
+ context_.Say(source,
+ "%s %s directive is not closely nested inside "
+ "SECTION or SECTIONS"_err_en_US,
+ ContextDirectiveAsFortran(),
+ parser::ToUpperCaseLetters(
+ parser::OmpCancelType::EnumToString(type)));
+ break;
+ case Fortran::parser::OmpCancelType::Type::Do:
+ context_.Say(source,
+ "%s %s directive is not closely nested inside "
+ "the construct that matches the DO clause type"_err_en_US,
+ ContextDirectiveAsFortran(),
+ parser::ToUpperCaseLetters(
+ parser::OmpCancelType::EnumToString(type)));
+ break;
+ case parser::OmpCancelType::Type::Parallel:
+ context_.Say(source,
+ "%s %s directive is not closely nested inside "
+ "the construct that matches the PARALLEL clause type"_err_en_US,
+ ContextDirectiveAsFortran(),
+ parser::ToUpperCaseLetters(
+ parser::OmpCancelType::EnumToString(type)));
+ break;
+ default:
+ break;
+ }
+ }
+}
+
void OmpStructureChecker::Enter(const parser::OmpEndBlockDirective &x) {
const auto &dir{std::get<parser::OmpBlockDirective>(x.t)};
ResetPartialContext(dir.source);
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index fcb117d7e4c40..2eebb8f705089 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -225,6 +225,8 @@ class OmpStructureChecker
void CheckCycleConstraints(const parser::OpenMPLoopConstruct &x);
void CheckDistLinear(const parser::OpenMPLoopConstruct &x);
void CheckSIMDNest(const parser::OpenMPConstruct &x);
+ void CheckCancellationNest(
+ const parser::CharBlock &source, const parser::OmpCancelType::Type &type);
std::int64_t GetOrdCollapseLevel(const parser::OpenMPLoopConstruct &x);
void CheckIfDoOrderedClause(const parser::OmpBlockDirective &blkDirectiv);
bool CheckReductionOperators(const parser::OmpClause::Reduction &);
diff --git a/flang/test/Semantics/omp-clause-validity01.f90 b/flang/test/Semantics/omp-clause-validity01.f90
index 79d3c1d6c2f9a..e4dd150459a49 100644
--- a/flang/test/Semantics/omp-clause-validity01.f90
+++ b/flang/test/Semantics/omp-clause-validity01.f90
@@ -494,9 +494,6 @@
!ERROR: RELAXED clause is not allowed on the FLUSH directive
!$omp flush relaxed
- !$omp cancel DO
- !$omp cancellation point parallel
-
! 2.13.2 critical Construct
! !$omp critical (first)
diff --git a/flang/test/Semantics/omp-nested-cancel.f90 b/flang/test/Semantics/omp-nested-cancel.f90
new file mode 100644
index 0000000000000..579d762a02fac
--- /dev/null
+++ b/flang/test/Semantics/omp-nested-cancel.f90
@@ -0,0 +1,250 @@
+! RUN: %S/test_errors.sh %s %t %flang -fopenmp
+! REQUIRES: shell
+
+! OpenMP Version 5.0
+! Check OpenMP construct validity for the following directives:
+! 2.18.1 Cancel Construct
+
+program main
+ integer :: i, N = 10
+ real :: a
+
+ !ERROR: CANCEL TASKGROUP directive is not closely nested inside TASK or TASKLOOP
+ !$omp cancel taskgroup
+
+ !ERROR: CANCEL SECTIONS directive is not closely nested inside SECTION or SECTIONS
+ !$omp cancel sections
+
+ !ERROR: CANCEL DO directive is not closely nested inside the construct that matches the DO clause type
+ !$omp cancel do
+
+ !ERROR: CANCEL PARALLEL directive is not closely nested inside the construct that matches the PARALLEL clause type
+ !$omp cancel parallel
+
+ !$omp parallel
+ !$omp sections
+ !$omp cancel sections
+ !$omp section
+ a = 3.14
+ !$omp end sections
+ !$omp end parallel
+
+ !$omp sections
+ !$omp section
+ !$omp cancel sections
+ a = 3.14
+ !$omp end sections
+
+ !$omp parallel
+ !ERROR: With SECTIONS clause, CANCEL construct cannot be closely nested inside PARALLEL construct
+ !$omp cancel sections
+ a = 3.14
+ !$omp end parallel
+
+ !$omp parallel sections
+ !$omp cancel sections
+ a = 3.14
+ !$omp end parallel sections
+
+ !$omp do
+ do i = 1, N
+ a = 3.14
+ !$omp cancel do
+ end do
+ !$omp end do
+
+ !$omp parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancel do
+ end do
+ !$omp end parallel do
+
+ !$omp target
+ !$omp teams
+ !$omp distribute parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancel do
+ end do
+ !$omp end distribute parallel do
+ !$omp end teams
+ !$omp end target
+
+ !$omp target
+ !$omp teams distribute parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancel do
+ end do
+ !$omp end teams distribute parallel do
+ !$omp end target
+
+ !$omp target teams distribute parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancel do
+ end do
+ !$omp end target teams distribute parallel do
+
+ !$omp target parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancel do
+ end do
+ !$omp end target parallel do
+
+ !$omp parallel
+ do i = 1, N
+ a = 3.14
+ !ERROR: With DO clause, CANCEL construct cannot be closely nested inside PARALLEL construct
+ !$omp cancel do
+ end do
+ !$omp end parallel
+
+ !$omp parallel
+ do i = 1, N
+ a = 3.14
+ !$omp cancel parallel
+ end do
+ !$omp end parallel
+
+ !$omp target parallel
+ do i = 1, N
+ a = 3.14
+ !$omp cancel parallel
+ end do
+ !$omp end target parallel
+
+ !$omp target parallel do
+ do i = 1, N
+ a = 3.14
+ !ERROR: With PARALLEL clause, CANCEL construct cannot be closely nested inside TARGET PARALLEL DO construct
+ !$omp cancel parallel
+ end do
+ !$omp end target parallel do
+
+ !$omp do
+ do i = 1, N
+ a = 3.14
+ !ERROR: With PARALLEL clause, CANCEL construct cannot be closely nested inside DO construct
+ !$omp cancel parallel
+ end do
+ !$omp end do
+
+contains
+ subroutine sub1()
+ !$omp task
+ !$omp cancel taskgroup
+ a = 3.14
+ !$omp end task
+
+ !$omp taskloop
+ do i = 1, N
+ !$omp parallel
+ !$omp end parallel
+ !$omp cancel taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+
+ !$omp taskloop nogroup
+ do i = 1, N
+ !$omp cancel taskgroup
+ a = 3.14
+ end do
+
+ !$omp parallel
+ !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region
+ !$omp cancel taskgroup
+ a = 3.14
+ !$omp end parallel
+
+ !$omp do
+ do i = 1, N
+ !$omp task
+ !$omp cancel taskgroup
+ a = 3.14
+ !$omp end task
+ end do
+ !$omp end do
+
+ !$omp parallel
+ !$omp taskgroup
+ !$omp task
+ !$omp cancel taskgroup
+ a = 3.14
+ !$omp end task
+ !$omp end taskgroup
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp task
+ !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region
+ !$omp cancel taskgroup
+ a = 3.14
+ !$omp end task
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp do
+ do i = 1, N
+ !$omp task
+ !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region
+ !$omp cancel taskgroup
+ a = 3.14
+ !$omp end task
+ end do
+ !$omp end do
+ !$omp end parallel
+
+ !$omp target parallel
+ !$omp task
+ !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region
+ !$omp cancel taskgroup
+ a = 3.14
+ !$omp end task
+ !$omp end target parallel
+
+ !$omp parallel
+ !$omp taskloop private(j) nogroup
+ do i = 1, N
+ !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region
+ !$omp cancel taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp taskloop
+ do i = 1, N
+ !$omp cancel taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp taskgroup
+ !$omp taskloop nogroup
+ do i = 1, N
+ !$omp cancel taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end taskgroup
+ !$omp end parallel
+
+ !$omp target parallel
+ !$omp taskloop nogroup
+ do i = 1, N
+ !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region
+ !$omp cancel taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end target parallel
+ end subroutine sub1
+
+end program main
diff --git a/flang/test/Semantics/omp-nested-cancellation-point.f90 b/flang/test/Semantics/omp-nested-cancellation-point.f90
new file mode 100644
index 0000000000000..a139bfae5d202
--- /dev/null
+++ b/flang/test/Semantics/omp-nested-cancellation-point.f90
@@ -0,0 +1,250 @@
+! RUN: %S/test_errors.sh %s %t %flang -fopenmp
+! REQUIRES: shell
+
+! OpenMP Version 5.0
+! Check OpenMP construct validity for the following directives:
+! 2.18.2 Cancellation Point Construct
+
+program main
+ integer :: i, N = 10
+ real :: a
+
+ !ERROR: CANCELLATION POINT TASKGROUP directive is not closely nested inside TASK or TASKLOOP
+ !$omp cancellation point taskgroup
+
+ !ERROR: CANCELLATION POINT SECTIONS directive is not closely nested inside SECTION or SECTIONS
+ !$omp cancellation point sections
+
+ !ERROR: CANCELLATION POINT DO directive is not closely nested inside the construct that matches the DO clause type
+ !$omp cancellation point do
+
+ !ERROR: CANCELLATION POINT PARALLEL directive is not closely nested inside the construct that matches the PARALLEL clause type
+ !$omp cancellation point parallel
+
+ !$omp parallel
+ !$omp sections
+ !$omp cancellation point sections
+ !$omp section
+ a = 3.14
+ !$omp end sections
+ !$omp end parallel
+
+ !$omp sections
+ !$omp section
+ !$omp cancellation point sections
+ a = 3.14
+ !$omp end sections
+
+ !$omp parallel
+ !ERROR: With SECTIONS clause, CANCELLATION POINT construct cannot be closely nested inside PARALLEL construct
+ !$omp cancellation point sections
+ a = 3.14
+ !$omp end parallel
+
+ !$omp parallel sections
+ !$omp cancellation point sections
+ a = 3.14
+ !$omp end parallel sections
+
+ !$omp do
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point do
+ end do
+ !$omp end do
+
+ !$omp parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point do
+ end do
+ !$omp end parallel do
+
+ !$omp target
+ !$omp teams
+ !$omp distribute parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point do
+ end do
+ !$omp end distribute parallel do
+ !$omp end teams
+ !$omp end target
+
+ !$omp target
+ !$omp teams distribute parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point do
+ end do
+ !$omp end teams distribute parallel do
+ !$omp end target
+
+ !$omp target teams distribute parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point do
+ end do
+ !$omp end target teams distribute parallel do
+
+ !$omp target parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point do
+ end do
+ !$omp end target parallel do
+
+ !$omp parallel
+ do i = 1, N
+ a = 3.14
+ !ERROR: With DO clause, CANCELLATION POINT construct cannot be closely nested inside PARALLEL construct
+ !$omp cancellation point do
+ end do
+ !$omp end parallel
+
+ !$omp parallel
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point parallel
+ end do
+ !$omp end parallel
+
+ !$omp target parallel
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point parallel
+ end do
+ !$omp end target parallel
+
+ !$omp target parallel do
+ do i = 1, N
+ a = 3.14
+ !ERROR: With PARALLEL clause, CANCELLATION POINT construct cannot be closely nested inside TARGET PARALLEL DO construct
+ !$omp cancellation point parallel
+ end do
+ !$omp end target parallel do
+
+ !$omp do
+ do i = 1, N
+ a = 3.14
+ !ERROR: With PARALLEL clause, CANCELLATION POINT construct cannot be closely nested inside DO construct
+ !$omp cancellation point parallel
+ end do
+ !$omp end do
+
+contains
+ subroutine sub1()
+ !$omp task
+ !$omp cancellation point taskgroup
+ a = 3.14
+ !$omp end task
+
+ !$omp taskloop
+ do i = 1, N
+ !$omp parallel
+ !$omp end parallel
+ !$omp cancellation point taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+
+ !$omp taskloop nogroup
+ do i = 1, N
+ !$omp cancellation point taskgroup
+ a = 3.14
+ end do
+
+ !$omp parallel
+ !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region
+ !$omp cancellation point taskgroup
+ a = 3.14
+ !$omp end parallel
+
+ !$omp do
+ do i = 1, N
+ !$omp task
+ !$omp cancellation point taskgroup
+ a = 3.14
+ !$omp end task
+ end do
+ !$omp end do
+
+ !$omp parallel
+ !$omp taskgroup
+ !$omp task
+ !$omp cancellation point taskgroup
+ a = 3.14
+ !$omp end task
+ !$omp end taskgroup
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp task
+ !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region
+ !$omp cancellation point taskgroup
+ a = 3.14
+ !$omp end task
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp do
+ do i = 1, N
+ !$omp task
+ !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region
+ !$omp cancellation point taskgroup
+ a = 3.14
+ !$omp end task
+ end do
+ !$omp end do
+ !$omp end parallel
+
+ !$omp target parallel
+ !$omp task
+ !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region
+ !$omp cancellation point taskgroup
+ a = 3.14
+ !$omp end task
+ !$omp end target parallel
+
+ !$omp parallel
+ !$omp taskloop private(j) nogroup
+ do i = 1, N
+ !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region
+ !$omp cancellation point taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp taskloop
+ do i = 1, N
+ !$omp cancellation point taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp taskgroup
+ !$omp taskloop nogroup
+ do i = 1, N
+ !$omp cancellation point taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end taskgroup
+ !$omp end parallel
+
+ !$omp target parallel
+ !$omp taskloop nogroup
+ do i = 1, N
+ !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region
+ !$omp cancellation point taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end target parallel
+ end subroutine sub1
+
+end program main
More information about the flang-commits
mailing list