Skip to content

Commit a1db874

Browse files
authored
[flang][openacc] Allow multiple clauses when in preceded by device_type (#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.
1 parent 5f864ba commit a1db874

File tree

4 files changed

+70
-6
lines changed

4 files changed

+70
-6
lines changed

flang/lib/Semantics/check-acc-structure.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,8 @@ void AccStructureChecker::Enter(const parser::AccClause::NumGangs &n) {
561561
/*warnInsteadOfError=*/GetContext().directive ==
562562
llvm::acc::Directive::ACCD_serial ||
563563
GetContext().directive == llvm::acc::Directive::ACCD_serial_loop);
564+
CheckAllowedOncePerGroup(
565+
llvm::acc::Clause::ACCC_num_gangs, llvm::acc::Clause::ACCC_device_type);
564566

565567
if (n.v.size() > 3)
566568
context_.Say(GetContext().clauseSource,
@@ -572,13 +574,17 @@ void AccStructureChecker::Enter(const parser::AccClause::NumWorkers &n) {
572574
/*warnInsteadOfError=*/GetContext().directive ==
573575
llvm::acc::Directive::ACCD_serial ||
574576
GetContext().directive == llvm::acc::Directive::ACCD_serial_loop);
577+
CheckAllowedOncePerGroup(
578+
llvm::acc::Clause::ACCC_num_workers, llvm::acc::Clause::ACCC_device_type);
575579
}
576580

577581
void AccStructureChecker::Enter(const parser::AccClause::VectorLength &n) {
578582
CheckAllowed(llvm::acc::Clause::ACCC_vector_length,
579583
/*warnInsteadOfError=*/GetContext().directive ==
580584
llvm::acc::Directive::ACCD_serial ||
581585
GetContext().directive == llvm::acc::Directive::ACCD_serial_loop);
586+
CheckAllowedOncePerGroup(llvm::acc::Clause::ACCC_vector_length,
587+
llvm::acc::Clause::ACCC_device_type);
582588
}
583589

584590
void AccStructureChecker::Enter(const parser::AccClause::Reduction &reduction) {

flang/lib/Semantics/check-directive-structure.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,10 @@ class DirectiveStructureChecker : public virtual BaseChecker {
349349

350350
void CheckAllowed(C clause, bool warnInsteadOfError = false);
351351

352+
// Check that the clause appears only once. The counter is reset when the
353+
// separator clause appears.
354+
void CheckAllowedOncePerGroup(C clause, C separator);
355+
352356
void CheckAtLeastOneClause();
353357

354358
void CheckNotAllowedIfClause(
@@ -545,6 +549,27 @@ void DirectiveStructureChecker<D, C, PC,
545549
}
546550
}
547551

552+
template <typename D, typename C, typename PC, std::size_t ClauseEnumSize>
553+
void DirectiveStructureChecker<D, C, PC,
554+
ClauseEnumSize>::CheckAllowedOncePerGroup(C clause, C separator) {
555+
bool clauseIsPresent = false;
556+
for (auto cl : GetContext().actualClauses) {
557+
if (cl == clause) {
558+
if (clauseIsPresent) {
559+
context_.Say(GetContext().clauseSource,
560+
"At most one %s clause can appear on the %s directive or in group separated by the %s clause"_err_en_US,
561+
parser::ToUpperCaseLetters(getClauseName(clause).str()),
562+
parser::ToUpperCaseLetters(GetContext().directiveSource.ToString()),
563+
parser::ToUpperCaseLetters(getClauseName(separator).str()));
564+
} else {
565+
clauseIsPresent = true;
566+
}
567+
}
568+
if (cl == separator)
569+
clauseIsPresent = false;
570+
}
571+
}
572+
548573
// Check the value of the clause is a constant positive integer.
549574
template <typename D, typename C, typename PC, std::size_t ClauseEnumSize>
550575
void DirectiveStructureChecker<D, C, PC,

flang/test/Semantics/OpenACC/acc-parallel.f90

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,37 @@ program openacc_parallel_validity
155155
end do
156156
!$acc end parallel
157157

158+
!ERROR: At most one NUM_GANGS clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
159+
!$acc parallel num_gangs(400) num_gangs(400)
160+
!$acc end parallel
161+
162+
!ERROR: At most one NUM_GANGS clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
163+
!$acc parallel device_type(nvidia) num_gangs(400) num_gangs(200)
164+
!$acc end parallel
165+
166+
!$acc parallel device_type(nvidia) num_gangs(400) device_type(radeon) num_gangs(200)
167+
!$acc end parallel
168+
169+
!ERROR: At most one NUM_WORKERS clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
170+
!$acc parallel num_workers(8) num_workers(4)
171+
!$acc end parallel
172+
173+
!ERROR: At most one NUM_WORKERS clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
174+
!$acc parallel device_type(nvidia) num_workers(8) num_workers(4)
175+
!$acc end parallel
176+
177+
!$acc parallel device_type(nvidia) num_workers(8) device_type(radeon) num_workers(4)
178+
!$acc end parallel
179+
180+
!ERROR: At most one VECTOR_LENGTH clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
181+
!$acc parallel vector_length(128) vector_length(124)
182+
!$acc end parallel
183+
184+
!ERROR: At most one VECTOR_LENGTH clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
185+
!$acc parallel device_type(nvidia) vector_length(256) vector_length(128)
186+
!$acc end parallel
187+
188+
!$acc parallel device_type(nvidia) vector_length(256) device_type(radeon) vector_length(128)
189+
!$acc end parallel
190+
158191
end program openacc_parallel_validity

llvm/include/llvm/Frontend/OpenACC/ACC.td

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -335,27 +335,27 @@ def ACC_Kernels : Directive<"kernels"> {
335335
def ACC_Parallel : Directive<"parallel"> {
336336
let allowedClauses = [
337337
VersionedClause<ACCC_Attach>,
338+
VersionedClause<ACCC_Async>,
338339
VersionedClause<ACCC_Copy>,
339340
VersionedClause<ACCC_Copyin>,
340341
VersionedClause<ACCC_Copyout>,
341342
VersionedClause<ACCC_Create>,
342343
VersionedClause<ACCC_DevicePtr>,
343344
VersionedClause<ACCC_DeviceType>,
344345
VersionedClause<ACCC_NoCreate>,
346+
VersionedClause<ACCC_NumGangs>,
347+
VersionedClause<ACCC_NumWorkers>,
345348
VersionedClause<ACCC_Present>,
346349
VersionedClause<ACCC_Private>,
347350
VersionedClause<ACCC_FirstPrivate>,
348351
VersionedClause<ACCC_Reduction>,
349-
VersionedClause<ACCC_Wait>
352+
VersionedClause<ACCC_Wait>,
353+
VersionedClause<ACCC_VectorLength>
350354
];
351355
let allowedOnceClauses = [
352-
VersionedClause<ACCC_Async>,
353356
VersionedClause<ACCC_Default>,
354357
VersionedClause<ACCC_If>,
355-
VersionedClause<ACCC_NumGangs>,
356-
VersionedClause<ACCC_NumWorkers>,
357-
VersionedClause<ACCC_Self>,
358-
VersionedClause<ACCC_VectorLength>
358+
VersionedClause<ACCC_Self>
359359
];
360360
}
361361

0 commit comments

Comments
 (0)