Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[flang][openacc] Fix clauses check with device_type #77389

Merged
merged 1 commit into from
Jan 9, 2024

Conversation

clementval
Copy link
Contributor

A couple of clauses are allowed multiple times when they are separated by a device_type clause. This patch updates the ACC.td file to move these clauses to the allowedClause list and the CheckAllowedOncePerGroup function is used to make sure they appear only once on the directive or for each device_type.

@llvmbot llvmbot added flang Flang issues not falling into any other category openacc flang:semantics labels Jan 8, 2024
@llvmbot
Copy link
Member

llvmbot commented Jan 8, 2024

@llvm/pr-subscribers-openacc

@llvm/pr-subscribers-flang-semantics

Author: Valentin Clement (バレンタイン クレメン) (clementval)

Changes

A couple of clauses are allowed multiple times when they are separated by a device_type clause. This patch updates the ACC.td file to move these clauses to the allowedClause list and the CheckAllowedOncePerGroup function is used to make sure they appear only once on the directive or for each device_type.


Full diff: https://github.com/llvm/llvm-project/pull/77389.diff

3 Files Affected:

  • (modified) flang/lib/Semantics/check-acc-structure.cpp (+24-4)
  • (modified) flang/test/Semantics/OpenACC/acc-loop.f90 (+37-3)
  • (modified) llvm/include/llvm/Frontend/OpenACC/ACC.td (+33-33)
diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp
index 932d5776a04680..4a5798a8a531a4 100644
--- a/flang/lib/Semantics/check-acc-structure.cpp
+++ b/flang/lib/Semantics/check-acc-structure.cpp
@@ -225,7 +225,8 @@ void AccStructureChecker::Leave(const parser::OpenACCCombinedConstruct &x) {
   case llvm::acc::Directive::ACCD_serial_loop:
     // Restriction - line 1004-1005
     CheckOnlyAllowedAfter(llvm::acc::Clause::ACCC_device_type,
-        computeConstructOnlyAllowedAfterDeviceTypeClauses);
+        computeConstructOnlyAllowedAfterDeviceTypeClauses |
+            loopOnlyAllowedAfterDeviceTypeClauses);
     if (doCons) {
       const parser::Block &block{std::get<parser::Block>(doCons->t)};
       CheckNoBranching(block, GetContext().directive, beginBlockDir.source);
@@ -388,11 +389,8 @@ CHECK_SIMPLE_CLAUSE(Nohost, ACCC_nohost)
 CHECK_SIMPLE_CLAUSE(Private, ACCC_private)
 CHECK_SIMPLE_CLAUSE(Read, ACCC_read)
 CHECK_SIMPLE_CLAUSE(Seq, ACCC_seq)
-CHECK_SIMPLE_CLAUSE(Tile, ACCC_tile)
 CHECK_SIMPLE_CLAUSE(UseDevice, ACCC_use_device)
-CHECK_SIMPLE_CLAUSE(Vector, ACCC_vector)
 CHECK_SIMPLE_CLAUSE(Wait, ACCC_wait)
-CHECK_SIMPLE_CLAUSE(Worker, ACCC_worker)
 CHECK_SIMPLE_CLAUSE(Write, ACCC_write)
 CHECK_SIMPLE_CLAUSE(Unknown, ACCC_unknown)
 
@@ -536,8 +534,28 @@ void AccStructureChecker::Enter(const parser::AccClause::DeviceType &d) {
   }
 }
 
+void AccStructureChecker::Enter(const parser::AccClause::Vector &g) {
+  CheckAllowed(llvm::acc::Clause::ACCC_vector);
+  CheckAllowedOncePerGroup(
+      llvm::acc::Clause::ACCC_vector, llvm::acc::Clause::ACCC_device_type);
+}
+
+void AccStructureChecker::Enter(const parser::AccClause::Worker &g) {
+  CheckAllowed(llvm::acc::Clause::ACCC_worker);
+  CheckAllowedOncePerGroup(
+      llvm::acc::Clause::ACCC_worker, llvm::acc::Clause::ACCC_device_type);
+}
+
+void AccStructureChecker::Enter(const parser::AccClause::Tile &g) {
+  CheckAllowed(llvm::acc::Clause::ACCC_tile);
+  CheckAllowedOncePerGroup(
+      llvm::acc::Clause::ACCC_tile, llvm::acc::Clause::ACCC_device_type);
+}
+
 void AccStructureChecker::Enter(const parser::AccClause::Gang &g) {
   CheckAllowed(llvm::acc::Clause::ACCC_gang);
+  CheckAllowedOncePerGroup(
+      llvm::acc::Clause::ACCC_gang, llvm::acc::Clause::ACCC_device_type);
 
   if (g.v) {
     bool hasNum = false;
@@ -665,6 +683,8 @@ void AccStructureChecker::Enter(const parser::AccClause::Self &x) {
 
 void AccStructureChecker::Enter(const parser::AccClause::Collapse &x) {
   CheckAllowed(llvm::acc::Clause::ACCC_collapse);
+  CheckAllowedOncePerGroup(
+      llvm::acc::Clause::ACCC_collapse, llvm::acc::Clause::ACCC_device_type);
   const parser::AccCollapseArg &accCollapseArg = x.v;
   const auto &collapseValue{
       std::get<parser::ScalarIntConstantExpr>(accCollapseArg.t)};
diff --git a/flang/test/Semantics/OpenACC/acc-loop.f90 b/flang/test/Semantics/OpenACC/acc-loop.f90
index f5d1e501a2b329..fde836852c51ed 100644
--- a/flang/test/Semantics/OpenACC/acc-loop.f90
+++ b/flang/test/Semantics/OpenACC/acc-loop.f90
@@ -63,7 +63,7 @@ program openacc_loop_validity
   !$acc end parallel
 
   !$acc parallel
-  !ERROR: At most one VECTOR clause can appear on the LOOP directive
+  !ERROR: At most one VECTOR clause can appear on the LOOP directive or in group separated by the DEVICE_TYPE clause
   !$acc loop vector vector(128)
   do i = 1, N
     a(i) = 3.14
@@ -99,7 +99,7 @@ program openacc_loop_validity
   !$acc end parallel
 
   !$acc parallel
-  !ERROR: At most one WORKER clause can appear on the LOOP directive
+  !ERROR: At most one WORKER clause can appear on the LOOP directive or in group separated by the DEVICE_TYPE clause
   !$acc loop worker worker(10)
   do i = 1, N
     a(i) = 3.14
@@ -135,13 +135,29 @@ program openacc_loop_validity
   !$acc end parallel
 
   !$acc parallel
-  !ERROR: At most one GANG clause can appear on the LOOP directive
+  !ERROR: At most one GANG clause can appear on the LOOP directive or in group separated by the DEVICE_TYPE clause
   !$acc loop gang gang(gang_size)
   do i = 1, N
     a(i) = 3.14
   end do
   !$acc end parallel
 
+  !$acc loop gang device_type(default) gang(gang_size)
+  do i = 1, N
+    a(i) = 3.14
+  end do
+
+  !ERROR: At most one GANG clause can appear on the PARALLEL LOOP directive or in group separated by the DEVICE_TYPE clause
+  !$acc parallel loop gang gang(gang_size)
+  do i = 1, N
+    a(i) = 3.14
+  end do
+
+  !$acc parallel loop gang device_type(default) gang(gang_size)
+  do i = 1, N
+    a(i) = 3.14
+  end do
+
   !$acc parallel
   !$acc loop gang(gang_size)
   do i = 1, N
@@ -283,4 +299,22 @@ program openacc_loop_validity
   end do
   !$acc end parallel
 
+  !$acc loop gang device_type(nvidia) gang(num: 8)
+  DO i = 1, n
+  END DO
+
+  !$acc loop vector device_type(default) vector(16)
+  DO i = 1, n
+  END DO
+
+  !$acc loop worker device_type(*) worker(8)
+  DO i = 1, n
+  END DO
+
+  !$acc loop device_type(multicore) collapse(2)
+  DO i = 1, n
+    DO j = 1, n
+    END DO
+  END DO
+
 end program openacc_loop_validity
diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td
index 013d18e160de46..0dbd934d83f064 100644
--- a/llvm/include/llvm/Frontend/OpenACC/ACC.td
+++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td
@@ -391,9 +391,7 @@ def ACC_Loop : Directive<"loop"> {
   let allowedClauses = [
     VersionedClause<ACCC_DeviceType>,
     VersionedClause<ACCC_Private>,
-    VersionedClause<ACCC_Reduction>
-  ];
-  let allowedOnceClauses = [
+    VersionedClause<ACCC_Reduction>,
     VersionedClause<ACCC_Collapse>,
     VersionedClause<ACCC_Gang>,
     VersionedClause<ACCC_Tile>,
@@ -421,15 +419,17 @@ def ACC_Init : Directive<"init"> {
 
 // 2.15.1
 def ACC_Routine : Directive<"routine"> {
-  let allowedOnceClauses = [
+  let allowedClauses = [
     VersionedClause<ACCC_Bind>,
     VersionedClause<ACCC_DeviceType>,
-    VersionedClause<ACCC_NoHost>,
     VersionedClause<ACCC_Gang>,
     VersionedClause<ACCC_Seq>,
     VersionedClause<ACCC_Vector>,
     VersionedClause<ACCC_Worker>
   ];
+  let allowedOnceClauses = [
+    VersionedClause<ACCC_NoHost>
+  ];
 }
 
 // 2.14.3
@@ -532,32 +532,32 @@ def ACC_HostData : Directive<"host_data"> {
 // 2.11
 def ACC_KernelsLoop : Directive<"kernels loop"> {
   let allowedClauses = [
+    VersionedClause<ACCC_Attach>,
+    VersionedClause<ACCC_Collapse>,
     VersionedClause<ACCC_Copy>,
     VersionedClause<ACCC_Copyin>,
     VersionedClause<ACCC_Copyout>,
     VersionedClause<ACCC_Create>,
+    VersionedClause<ACCC_DevicePtr>,
     VersionedClause<ACCC_DeviceType>,
+    VersionedClause<ACCC_Gang>,
     VersionedClause<ACCC_NoCreate>,
+    VersionedClause<ACCC_NumGangs>,
+    VersionedClause<ACCC_NumWorkers>,
     VersionedClause<ACCC_Present>,
     VersionedClause<ACCC_Private>,
     VersionedClause<ACCC_Reduction>,
-    VersionedClause<ACCC_DevicePtr>,
-    VersionedClause<ACCC_Attach>,
-    VersionedClause<ACCC_Wait>
+    VersionedClause<ACCC_Tile>,
+    VersionedClause<ACCC_Vector>,
+    VersionedClause<ACCC_VectorLength>,
+    VersionedClause<ACCC_Wait>,
+    VersionedClause<ACCC_Worker>
   ];
   let allowedOnceClauses = [
     VersionedClause<ACCC_Async>,
-    VersionedClause<ACCC_Collapse>,
     VersionedClause<ACCC_Default>,
-    VersionedClause<ACCC_Gang>,
     VersionedClause<ACCC_If>,
-    VersionedClause<ACCC_NumGangs>,
-    VersionedClause<ACCC_NumWorkers>,
-    VersionedClause<ACCC_Self>,
-    VersionedClause<ACCC_Tile>,
-    VersionedClause<ACCC_Vector>,
-    VersionedClause<ACCC_VectorLength>,
-    VersionedClause<ACCC_Worker>
+    VersionedClause<ACCC_Self>
   ];
   let allowedExclusiveClauses = [
     VersionedClause<ACCC_Auto>,
@@ -570,6 +570,7 @@ def ACC_KernelsLoop : Directive<"kernels loop"> {
 def ACC_ParallelLoop : Directive<"parallel loop"> {
   let allowedClauses = [
     VersionedClause<ACCC_Attach>,
+    VersionedClause<ACCC_Collapse>,
     VersionedClause<ACCC_Copy>,
     VersionedClause<ACCC_Copyin>,
     VersionedClause<ACCC_Copyout>,
@@ -577,25 +578,24 @@ def ACC_ParallelLoop : Directive<"parallel loop"> {
     VersionedClause<ACCC_DevicePtr>,
     VersionedClause<ACCC_DeviceType>,
     VersionedClause<ACCC_FirstPrivate>,
+    VersionedClause<ACCC_Gang>,
     VersionedClause<ACCC_NoCreate>,
+    VersionedClause<ACCC_NumGangs>,
+    VersionedClause<ACCC_NumWorkers>,
     VersionedClause<ACCC_Present>,
     VersionedClause<ACCC_Private>,
     VersionedClause<ACCC_Reduction>,
     VersionedClause<ACCC_Tile>,
-    VersionedClause<ACCC_Wait>
+    VersionedClause<ACCC_Vector>,
+    VersionedClause<ACCC_VectorLength>,
+    VersionedClause<ACCC_Wait>,
+    VersionedClause<ACCC_Worker>
   ];
   let allowedOnceClauses = [
     VersionedClause<ACCC_Async>,
-    VersionedClause<ACCC_Collapse>,
     VersionedClause<ACCC_Default>,
-    VersionedClause<ACCC_Gang>,
     VersionedClause<ACCC_If>,
-    VersionedClause<ACCC_NumGangs>,
-    VersionedClause<ACCC_NumWorkers>,
-    VersionedClause<ACCC_Self>,
-    VersionedClause<ACCC_Vector>,
-    VersionedClause<ACCC_VectorLength>,
-    VersionedClause<ACCC_Worker>
+    VersionedClause<ACCC_Self>
   ];
   let allowedExclusiveClauses = [
     VersionedClause<ACCC_Auto>,
@@ -608,6 +608,7 @@ def ACC_ParallelLoop : Directive<"parallel loop"> {
 def ACC_SerialLoop : Directive<"serial loop"> {
   let allowedClauses = [
     VersionedClause<ACCC_Attach>,
+    VersionedClause<ACCC_Collapse>,
     VersionedClause<ACCC_Copy>,
     VersionedClause<ACCC_Copyin>,
     VersionedClause<ACCC_Copyout>,
@@ -615,22 +616,21 @@ def ACC_SerialLoop : Directive<"serial loop"> {
     VersionedClause<ACCC_DevicePtr>,
     VersionedClause<ACCC_DeviceType>,
     VersionedClause<ACCC_FirstPrivate>,
+    VersionedClause<ACCC_Gang>,
     VersionedClause<ACCC_NoCreate>,
     VersionedClause<ACCC_Present>,
     VersionedClause<ACCC_Private>,
     VersionedClause<ACCC_Reduction>,
-    VersionedClause<ACCC_Wait>
+    VersionedClause<ACCC_Tile>,
+    VersionedClause<ACCC_Vector>,
+    VersionedClause<ACCC_Wait>,
+    VersionedClause<ACCC_Worker>
   ];
   let allowedOnceClauses = [
     VersionedClause<ACCC_Async>,
-    VersionedClause<ACCC_Collapse>,
     VersionedClause<ACCC_Default>,
-    VersionedClause<ACCC_Gang>,
     VersionedClause<ACCC_If>,
-    VersionedClause<ACCC_Self>,
-    VersionedClause<ACCC_Tile>,
-    VersionedClause<ACCC_Vector>,
-    VersionedClause<ACCC_Worker>
+    VersionedClause<ACCC_Self>
   ];
   let allowedExclusiveClauses = [
     VersionedClause<ACCC_Auto>,

Copy link
Contributor

@razvanlupusoru razvanlupusoru left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@clementval clementval merged commit ed64042 into llvm:main Jan 9, 2024
6 of 7 checks passed
@clementval clementval deleted the acc_device_type_clauses branch January 18, 2024 17:14
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
A couple of clauses are allowed multiple times when they are separated
by a device_type clause. This patch updates the ACC.td file to move
these clauses to the `allowedClause` list and the
`CheckAllowedOncePerGroup` function is used to make sure they appear
only once on the directive or for each device_type.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:semantics flang Flang issues not falling into any other category openacc
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants