[flang-commits] [flang] [llvm] [flang][openacc] Allow multiple clauses when in preceded by device_type (PR #73976)
Valentin Clement バレンタイン クレメン via flang-commits
flang-commits at lists.llvm.org
Thu Nov 30 12:10:29 PST 2023
https://github.com/clementval created https://github.com/llvm/llvm-project/pull/73976
Some clauses can be repeated on the compute construct when they are placed after `device_type`. The semantic check was reporting an error for these cases. This patch fixes this.
>From 9714b10ff00d128e274c2170bdeea36751795759 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Thu, 30 Nov 2023 11:47:04 -0800
Subject: [PATCH] [flang][openacc] Allow multiple clauses when in preceded by
device_type
---
flang/lib/Semantics/check-acc-structure.cpp | 6 ++++
.../lib/Semantics/check-directive-structure.h | 25 ++++++++++++++
flang/test/Semantics/OpenACC/acc-parallel.f90 | 33 +++++++++++++++++++
llvm/include/llvm/Frontend/OpenACC/ACC.td | 12 +++----
4 files changed, 70 insertions(+), 6 deletions(-)
diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp
index abda9409efd336b..932d5776a04680c 100644
--- a/flang/lib/Semantics/check-acc-structure.cpp
+++ b/flang/lib/Semantics/check-acc-structure.cpp
@@ -561,6 +561,8 @@ void AccStructureChecker::Enter(const parser::AccClause::NumGangs &n) {
/*warnInsteadOfError=*/GetContext().directive ==
llvm::acc::Directive::ACCD_serial ||
GetContext().directive == llvm::acc::Directive::ACCD_serial_loop);
+ CheckAllowedOncePerGroup(
+ llvm::acc::Clause::ACCC_num_gangs, llvm::acc::Clause::ACCC_device_type);
if (n.v.size() > 3)
context_.Say(GetContext().clauseSource,
@@ -572,6 +574,8 @@ void AccStructureChecker::Enter(const parser::AccClause::NumWorkers &n) {
/*warnInsteadOfError=*/GetContext().directive ==
llvm::acc::Directive::ACCD_serial ||
GetContext().directive == llvm::acc::Directive::ACCD_serial_loop);
+ CheckAllowedOncePerGroup(
+ llvm::acc::Clause::ACCC_num_workers, llvm::acc::Clause::ACCC_device_type);
}
void AccStructureChecker::Enter(const parser::AccClause::VectorLength &n) {
@@ -579,6 +583,8 @@ void AccStructureChecker::Enter(const parser::AccClause::VectorLength &n) {
/*warnInsteadOfError=*/GetContext().directive ==
llvm::acc::Directive::ACCD_serial ||
GetContext().directive == llvm::acc::Directive::ACCD_serial_loop);
+ CheckAllowedOncePerGroup(llvm::acc::Clause::ACCC_vector_length,
+ llvm::acc::Clause::ACCC_device_type);
}
void AccStructureChecker::Enter(const parser::AccClause::Reduction &reduction) {
diff --git a/flang/lib/Semantics/check-directive-structure.h b/flang/lib/Semantics/check-directive-structure.h
index 84240b87f47ec4b..f7a6233a32edddb 100644
--- a/flang/lib/Semantics/check-directive-structure.h
+++ b/flang/lib/Semantics/check-directive-structure.h
@@ -349,6 +349,10 @@ class DirectiveStructureChecker : public virtual BaseChecker {
void CheckAllowed(C clause, bool warnInsteadOfError = false);
+ // Check that the clause appears only once. The counter is reset when the
+ // separator clause appears.
+ void CheckAllowedOncePerGroup(C clause, C separator);
+
void CheckAtLeastOneClause();
void CheckNotAllowedIfClause(
@@ -545,6 +549,27 @@ void DirectiveStructureChecker<D, C, PC,
}
}
+template <typename D, typename C, typename PC, std::size_t ClauseEnumSize>
+void DirectiveStructureChecker<D, C, PC,
+ ClauseEnumSize>::CheckAllowedOncePerGroup(C clause, C separator) {
+ bool clauseIsPresent = false;
+ for (auto cl : GetContext().actualClauses) {
+ if (cl == clause) {
+ if (clauseIsPresent) {
+ context_.Say(GetContext().clauseSource,
+ "At most one %s clause can appear on the %s directive or in group separated by the %s clause"_err_en_US,
+ parser::ToUpperCaseLetters(getClauseName(clause).str()),
+ parser::ToUpperCaseLetters(GetContext().directiveSource.ToString()),
+ parser::ToUpperCaseLetters(getClauseName(separator).str()));
+ } else {
+ clauseIsPresent = true;
+ }
+ }
+ if (cl == separator)
+ clauseIsPresent = false;
+ }
+}
+
// Check the value of the clause is a constant positive integer.
template <typename D, typename C, typename PC, std::size_t ClauseEnumSize>
void DirectiveStructureChecker<D, C, PC,
diff --git a/flang/test/Semantics/OpenACC/acc-parallel.f90 b/flang/test/Semantics/OpenACC/acc-parallel.f90
index c87d321593ddf3d..3f17d8fc862a678 100644
--- a/flang/test/Semantics/OpenACC/acc-parallel.f90
+++ b/flang/test/Semantics/OpenACC/acc-parallel.f90
@@ -155,4 +155,37 @@ program openacc_parallel_validity
end do
!$acc end parallel
+ !ERROR: At most one NUM_GANGS clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
+ !$acc parallel num_gangs(400) num_gangs(400)
+ !$acc end parallel
+
+ !ERROR: At most one NUM_GANGS clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
+ !$acc parallel device_type(nvidia) num_gangs(400) num_gangs(200)
+ !$acc end parallel
+
+ !$acc parallel device_type(nvidia) num_gangs(400) device_type(radeon) num_gangs(200)
+ !$acc end parallel
+
+ !ERROR: At most one NUM_WORKERS clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
+ !$acc parallel num_workers(8) num_workers(4)
+ !$acc end parallel
+
+ !ERROR: At most one NUM_WORKERS clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
+ !$acc parallel device_type(nvidia) num_workers(8) num_workers(4)
+ !$acc end parallel
+
+ !$acc parallel device_type(nvidia) num_workers(8) device_type(radeon) num_workers(4)
+ !$acc end parallel
+
+ !ERROR: At most one VECTOR_LENGTH clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
+ !$acc parallel vector_length(128) vector_length(124)
+ !$acc end parallel
+
+ !ERROR: At most one VECTOR_LENGTH clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
+ !$acc parallel device_type(nvidia) vector_length(256) vector_length(128)
+ !$acc end parallel
+
+ !$acc parallel device_type(nvidia) vector_length(256) device_type(radeon) vector_length(128)
+ !$acc end parallel
+
end program openacc_parallel_validity
diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td
index 692ddefb1b4cc2e..013d18e160de461 100644
--- a/llvm/include/llvm/Frontend/OpenACC/ACC.td
+++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td
@@ -335,6 +335,7 @@ def ACC_Kernels : Directive<"kernels"> {
def ACC_Parallel : Directive<"parallel"> {
let allowedClauses = [
VersionedClause<ACCC_Attach>,
+ VersionedClause<ACCC_Async>,
VersionedClause<ACCC_Copy>,
VersionedClause<ACCC_Copyin>,
VersionedClause<ACCC_Copyout>,
@@ -342,20 +343,19 @@ def ACC_Parallel : Directive<"parallel"> {
VersionedClause<ACCC_DevicePtr>,
VersionedClause<ACCC_DeviceType>,
VersionedClause<ACCC_NoCreate>,
+ VersionedClause<ACCC_NumGangs>,
+ VersionedClause<ACCC_NumWorkers>,
VersionedClause<ACCC_Present>,
VersionedClause<ACCC_Private>,
VersionedClause<ACCC_FirstPrivate>,
VersionedClause<ACCC_Reduction>,
- VersionedClause<ACCC_Wait>
+ VersionedClause<ACCC_Wait>,
+ VersionedClause<ACCC_VectorLength>
];
let allowedOnceClauses = [
- VersionedClause<ACCC_Async>,
VersionedClause<ACCC_Default>,
VersionedClause<ACCC_If>,
- VersionedClause<ACCC_NumGangs>,
- VersionedClause<ACCC_NumWorkers>,
- VersionedClause<ACCC_Self>,
- VersionedClause<ACCC_VectorLength>
+ VersionedClause<ACCC_Self>
];
}
More information about the flang-commits
mailing list