This is an archive of the discontinued LLVM Phabricator instance.

[flang][OpenMP] Add semantic check for cancellation nesting
ClosedPublic

Authored by peixin on Jul 22 2021, 4:18 AM.

Details

Summary

This patch implements the following check 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.

Diff Detail

Event Timeline

peixin created this revision.Jul 22 2021, 4:18 AM
peixin requested review of this revision.Jul 22 2021, 4:18 AM
peixin added a comment.EditedJul 22 2021, 4:20 AM

Currently, I do not implement the semantic check for the following two scenarios, which should not be allowed according to OpenMP Version 5.0 Specification.

!$omp task
  !$omp cancel taskgroup
!$omp end task
!$omp taskloop nogroup
  do i = 1, N
    !$omp cancel taskgroup
    a = 3.14;
  end do

They are supported by gfortran and current clang. Should we report errors or warnings or just ignore it? Or maybe my understanding is incorrect.

kiranchandramohan requested changes to this revision.Jul 27 2021, 2:35 PM

Currently, I do not implement the semantic check for the following two scenarios, which should not be allowed according to OpenMP Version 5.0 Specification.

!$omp task
  !$omp cancel taskgroup
!$omp end task
!$omp taskloop nogroup
  do i = 1, N
    !$omp cancel taskgroup
    a = 3.14;
  end do

They are supported by gfortran and current clang. Should we report errors or warnings or just ignore it? Or maybe my understanding is incorrect.

The region is a dynamic concept, unlike constructs. So nesting of regions is satisfied if the taskgroup is enclosing somewhere in the call sequence. This is difficult to test since it requires interprocedural analysis.

subroutine two
!$omp task
  !$omp cancel taskgroup
!$omp end task
end subroutine two

subroutine one
!$omp taskgroup
call two()
!$omp end taskgroup
end subroutine one

I think the current implementation does not catch the following case which is clearly not permitted by the standard.
(Note the definition of closely nested region. A region nested inside another region with no parallel region nested between them)

subroutine sb
!$omp parallel
  !$omp task
    !$omp cancel taskgroup
  !$omp end task
!$omp end parallel
end subroutine
flang/lib/Semantics/check-omp-structure.cpp
934

Nit: Can you provide a better error message here? Like "%s directive is not closely nested inside %s"

This revision now requires changes to proceed.Jul 27 2021, 2:35 PM
peixin updated this revision to Diff 362674.Jul 29 2021, 1:39 AM
peixin added a reviewer: Chuanfeng.

@kiranchandramohan Thanks for the explanation and review.

Add the test case you provided that I did not catch in last patch and other three scenarios that should also be not permitted by the standard. The implementation of cancel taskgroup is fixed to cover these test scenarios.

flang/lib/Semantics/check-omp-structure.cpp
934

Fixed the error message. Could you please check if it is ok now?

Found two more scenarios that are not covered. Please wait for the new patch to review in a few minutes.

peixin updated this revision to Diff 362719.Jul 29 2021, 4:48 AM
peixin set the repository for this revision to rG LLVM Github Monorepo.

Add the following test scenarios, which is taskgroup nested between parallel and cancel taskgroup and fix the implementation by break the for loop when encountering taskgroup or parallel/target parallel.

!$omp parallel
!$omp taskgroup
!$omp task
!$omp cancel taskgroup
a = 3.14
!$omp end task
!$omp end taskgroup
!$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

By the way, according to the description of target parallel construct in OpenMP 5.0 Specification, the target parallel construct should have the similar behavior as the above parallel construct.

Target Parallel Description
The semantics are identical to explicitly specifying a target directive immediately followed by a parallel directive.
kiranchandramohan accepted this revision.Aug 6 2021, 3:57 PM

LGTM. Thanks for the patch and the patience.

flang/lib/Semantics/check-omp-structure.cpp
885

Nit: Add a comment here on what is checked in the if portion.

904

Nit: Can you add a comment signifying the importance of 3?

957

Nit: Add a comment here on what is checked in the else portion.

This revision is now accepted and ready to land.Aug 6 2021, 3:57 PM
peixin updated this revision to Diff 365166.Aug 9 2021, 5:33 AM

@kiranchandramohan Thanks for the review. Added the comments.

This revision was automatically updated to reflect the committed changes.

It would seem that your patch may have broken some builds:
https://lab.llvm.org/buildbot/#/builders/175/builds/2077

There are default cases in switches, where those defaults can not be reached because all cases are covered.

Proibably relatively easy to fix by deleting those default statements.