Skip to content

Commit c8ad802

Browse files
committed
[flang][openacc] Carry device dependent info for routine in the module file
1 parent a6d4017 commit c8ad802

File tree

9 files changed

+144
-45
lines changed

9 files changed

+144
-45
lines changed

flang/include/flang/Common/Fortran.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ ENUM_CLASS(CUDASubprogramAttrs, Host, Device, HostDevice, Global, Grid_Global)
8787
// CUDA data attributes; mutually exclusive
8888
ENUM_CLASS(CUDADataAttr, Constant, Device, Managed, Pinned, Shared, Texture)
8989

90+
// OpenACC device types
91+
ENUM_CLASS(
92+
OpenACCDeviceType, Star, Default, Nvidia, Radeon, Host, Multicore, None)
93+
9094
// OpenMP atomic_default_mem_order clause allowed values
9195
ENUM_CLASS(OmpAtomicDefaultMemOrderType, SeqCst, AcqRel, Relaxed)
9296

flang/include/flang/Parser/dump-parse-tree.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class ParseTreeDumper {
4848
NODE(std, uint64_t)
4949
NODE_ENUM(common, CUDADataAttr)
5050
NODE_ENUM(common, CUDASubprogramAttrs)
51+
NODE_ENUM(common, OpenACCDeviceType)
5152
NODE(format, ControlEditDesc)
5253
NODE(format::ControlEditDesc, Kind)
5354
NODE(format, DerivedTypeDataEditDesc)
@@ -101,7 +102,7 @@ class ParseTreeDumper {
101102
NODE(parser, AccSelfClause)
102103
NODE(parser, AccStandaloneDirective)
103104
NODE(parser, AccDeviceTypeExpr)
104-
NODE_ENUM(parser::AccDeviceTypeExpr, Device)
105+
105106
NODE(parser, AccDeviceTypeExprList)
106107
NODE(parser, AccTileExpr)
107108
NODE(parser, AccTileExprList)

flang/include/flang/Parser/parse-tree.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4072,8 +4072,8 @@ struct AccWaitArgument {
40724072
};
40734073

40744074
struct AccDeviceTypeExpr {
4075-
ENUM_CLASS(Device, Star, Default, Nvidia, Radeon, Host, Multicore)
4076-
WRAPPER_CLASS_BOILERPLATE(AccDeviceTypeExpr, Device);
4075+
WRAPPER_CLASS_BOILERPLATE(
4076+
AccDeviceTypeExpr, Fortran::common::OpenACCDeviceType);
40774077
CharBlock source;
40784078
};
40794079

flang/include/flang/Semantics/symbol.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ class WithBindName {
112112
bool isExplicitBindName_{false};
113113
};
114114

115-
class OpenACCRoutineInfo {
115+
// Device type specific OpenACC routine information
116+
class OpenACCRoutineDeviceTypeInfo {
116117
public:
117118
bool isSeq() const { return isSeq_; }
118119
void set_isSeq(bool value = true) { isSeq_ = value; }
@@ -124,21 +125,43 @@ class OpenACCRoutineInfo {
124125
void set_isGang(bool value = true) { isGang_ = value; }
125126
unsigned gangDim() const { return gangDim_; }
126127
void set_gangDim(unsigned value) { gangDim_ = value; }
127-
bool isNohost() const { return isNohost_; }
128-
void set_isNohost(bool value = true) { isNohost_ = value; }
129128
const std::string *bindName() const {
130129
return bindName_ ? &*bindName_ : nullptr;
131130
}
132131
void set_bindName(std::string &&name) { bindName_ = std::move(name); }
132+
void set_dType(Fortran::common::OpenACCDeviceType dType) {
133+
deviceType_ = dType;
134+
}
135+
Fortran::common::OpenACCDeviceType dType() const { return deviceType_; }
133136

134137
private:
135138
bool isSeq_{false};
136139
bool isVector_{false};
137140
bool isWorker_{false};
138141
bool isGang_{false};
139142
unsigned gangDim_{0};
140-
bool isNohost_{false};
141143
std::optional<std::string> bindName_;
144+
Fortran::common::OpenACCDeviceType deviceType_{
145+
Fortran::common::OpenACCDeviceType::None};
146+
};
147+
148+
// OpenACC routine information. Device independent info are stored on the
149+
// OpenACCRoutineInfo instance while device dependent info are stored
150+
// in as objects in the OpenACCRoutineDeviceTypeInfo list.
151+
class OpenACCRoutineInfo : public OpenACCRoutineDeviceTypeInfo {
152+
public:
153+
bool isNohost() const { return isNohost_; }
154+
void set_isNohost(bool value = true) { isNohost_ = value; }
155+
std::list<OpenACCRoutineDeviceTypeInfo> &deviceTypeInfos() {
156+
return deviceTypeInfos_;
157+
}
158+
void add_deviceTypeInfo(OpenACCRoutineDeviceTypeInfo &info) {
159+
deviceTypeInfos_.push_back(info);
160+
}
161+
162+
private:
163+
std::list<OpenACCRoutineDeviceTypeInfo> deviceTypeInfos_;
164+
bool isNohost_{false};
142165
};
143166

144167
// A subroutine or function definition, or a subprogram interface defined

flang/lib/Lower/OpenACC.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,20 +1483,22 @@ genAsyncClause(Fortran::lower::AbstractConverter &converter,
14831483
}
14841484

14851485
static mlir::acc::DeviceType
1486-
getDeviceType(Fortran::parser::AccDeviceTypeExpr::Device device) {
1486+
getDeviceType(Fortran::common::OpenACCDeviceType device) {
14871487
switch (device) {
1488-
case Fortran::parser::AccDeviceTypeExpr::Device::Star:
1488+
case Fortran::common::OpenACCDeviceType::Star:
14891489
return mlir::acc::DeviceType::Star;
1490-
case Fortran::parser::AccDeviceTypeExpr::Device::Default:
1490+
case Fortran::common::OpenACCDeviceType::Default:
14911491
return mlir::acc::DeviceType::Default;
1492-
case Fortran::parser::AccDeviceTypeExpr::Device::Nvidia:
1492+
case Fortran::common::OpenACCDeviceType::Nvidia:
14931493
return mlir::acc::DeviceType::Nvidia;
1494-
case Fortran::parser::AccDeviceTypeExpr::Device::Radeon:
1494+
case Fortran::common::OpenACCDeviceType::Radeon:
14951495
return mlir::acc::DeviceType::Radeon;
1496-
case Fortran::parser::AccDeviceTypeExpr::Device::Host:
1496+
case Fortran::common::OpenACCDeviceType::Host:
14971497
return mlir::acc::DeviceType::Host;
1498-
case Fortran::parser::AccDeviceTypeExpr::Device::Multicore:
1498+
case Fortran::common::OpenACCDeviceType::Multicore:
14991499
return mlir::acc::DeviceType::Multicore;
1500+
case Fortran::common::OpenACCDeviceType::None:
1501+
return mlir::acc::DeviceType::None;
15001502
}
15011503
return mlir::acc::DeviceType::None;
15021504
}

flang/lib/Parser/openacc-parsers.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ TYPE_PARSER(construct<AccSizeExpr>(scalarIntExpr) ||
5454
TYPE_PARSER(construct<AccSizeExprList>(nonemptyList(Parser<AccSizeExpr>{})))
5555

5656
TYPE_PARSER(sourced(construct<AccDeviceTypeExpr>(
57-
first("*" >> pure(AccDeviceTypeExpr::Device::Star),
58-
"DEFAULT" >> pure(AccDeviceTypeExpr::Device::Default),
59-
"NVIDIA" >> pure(AccDeviceTypeExpr::Device::Nvidia),
60-
"ACC_DEVICE_NVIDIA" >> pure(AccDeviceTypeExpr::Device::Nvidia),
61-
"RADEON" >> pure(AccDeviceTypeExpr::Device::Radeon),
62-
"HOST" >> pure(AccDeviceTypeExpr::Device::Host),
63-
"MULTICORE" >> pure(AccDeviceTypeExpr::Device::Multicore)))))
57+
first("*" >> pure(Fortran::common::OpenACCDeviceType::Star),
58+
"DEFAULT" >> pure(Fortran::common::OpenACCDeviceType::Default),
59+
"NVIDIA" >> pure(Fortran::common::OpenACCDeviceType::Nvidia),
60+
"ACC_DEVICE_NVIDIA" >> pure(Fortran::common::OpenACCDeviceType::Nvidia),
61+
"RADEON" >> pure(Fortran::common::OpenACCDeviceType::Radeon),
62+
"HOST" >> pure(Fortran::common::OpenACCDeviceType::Host),
63+
"MULTICORE" >> pure(Fortran::common::OpenACCDeviceType::Multicore)))))
6464

6565
TYPE_PARSER(
6666
construct<AccDeviceTypeExprList>(nonemptyList(Parser<AccDeviceTypeExpr>{})))

flang/lib/Semantics/mod-file.cpp

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -491,31 +491,51 @@ void ModFileWriter::PutDECStructure(
491491
static const Attrs subprogramPrefixAttrs{Attr::ELEMENTAL, Attr::IMPURE,
492492
Attr::MODULE, Attr::NON_RECURSIVE, Attr::PURE, Attr::RECURSIVE};
493493

494+
static void PutOpenACCDeviceTypeRoutineInfo(
495+
llvm::raw_ostream &os, const OpenACCRoutineDeviceTypeInfo &info) {
496+
if (info.isSeq()) {
497+
os << " seq";
498+
}
499+
if (info.isGang()) {
500+
os << " gang";
501+
if (info.gangDim() > 0) {
502+
os << "(dim: " << info.gangDim() << ")";
503+
}
504+
}
505+
if (info.isVector()) {
506+
os << " vector";
507+
}
508+
if (info.isWorker()) {
509+
os << " worker";
510+
}
511+
if (info.bindName()) {
512+
os << " bind(" << *info.bindName() << ")";
513+
}
514+
}
515+
494516
static void PutOpenACCRoutineInfo(
495517
llvm::raw_ostream &os, const SubprogramDetails &details) {
496518
for (auto info : details.openACCRoutineInfos()) {
497519
os << "!$acc routine";
498-
if (info.isSeq()) {
499-
os << " seq";
500-
}
501-
if (info.isGang()) {
502-
os << " gang";
503-
if (info.gangDim() > 0) {
504-
os << "(dim: " << info.gangDim() << ")";
505-
}
506-
}
507-
if (info.isVector()) {
508-
os << " vector";
509-
}
510-
if (info.isWorker()) {
511-
os << " worker";
512-
}
520+
521+
PutOpenACCDeviceTypeRoutineInfo(os, info);
522+
513523
if (info.isNohost()) {
514524
os << " nohost";
515525
}
516-
if (info.bindName()) {
517-
os << " bind(" << *info.bindName() << ")";
526+
527+
for (auto dtype : info.deviceTypeInfos()) {
528+
os << " device_type(";
529+
if (dtype.dType() == common::OpenACCDeviceType::Star) {
530+
os << "*";
531+
} else {
532+
os << parser::ToLowerCaseLetters(common::EnumToString(dtype.dType()));
533+
}
534+
os << ")";
535+
536+
PutOpenACCDeviceTypeRoutineInfo(os, dtype);
518537
}
538+
519539
os << "\n";
520540
}
521541
}

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -945,33 +945,58 @@ void AccAttributeVisitor::AddRoutineInfoToSymbol(
945945
const auto &clauses = std::get<Fortran::parser::AccClauseList>(x.t);
946946
for (const Fortran::parser::AccClause &clause : clauses.v) {
947947
if (std::get_if<Fortran::parser::AccClause::Seq>(&clause.u)) {
948-
info.set_isSeq();
948+
if (info.deviceTypeInfos().empty()) {
949+
info.set_isSeq();
950+
} else {
951+
info.deviceTypeInfos().back().set_isSeq();
952+
}
949953
} else if (const auto *gangClause =
950954
std::get_if<Fortran::parser::AccClause::Gang>(&clause.u)) {
951-
info.set_isGang();
955+
if (info.deviceTypeInfos().empty()) {
956+
info.set_isGang();
957+
} else {
958+
info.deviceTypeInfos().back().set_isGang();
959+
}
952960
if (gangClause->v) {
953961
const Fortran::parser::AccGangArgList &x = *gangClause->v;
954962
for (const Fortran::parser::AccGangArg &gangArg : x.v) {
955963
if (const auto *dim =
956964
std::get_if<Fortran::parser::AccGangArg::Dim>(&gangArg.u)) {
957965
if (const auto v{EvaluateInt64(context_, dim->v)}) {
958-
info.set_gangDim(*v);
966+
if (info.deviceTypeInfos().empty()) {
967+
info.set_gangDim(*v);
968+
} else {
969+
info.deviceTypeInfos().back().set_gangDim(*v);
970+
}
959971
}
960972
}
961973
}
962974
}
963975
} else if (std::get_if<Fortran::parser::AccClause::Vector>(&clause.u)) {
964-
info.set_isVector();
976+
if (info.deviceTypeInfos().empty()) {
977+
info.set_isVector();
978+
} else {
979+
info.deviceTypeInfos().back().set_isVector();
980+
}
965981
} else if (std::get_if<Fortran::parser::AccClause::Worker>(&clause.u)) {
966-
info.set_isWorker();
982+
if (info.deviceTypeInfos().empty()) {
983+
info.set_isWorker();
984+
} else {
985+
info.deviceTypeInfos().back().set_isWorker();
986+
}
967987
} else if (std::get_if<Fortran::parser::AccClause::Nohost>(&clause.u)) {
968988
info.set_isNohost();
969989
} else if (const auto *bindClause =
970990
std::get_if<Fortran::parser::AccClause::Bind>(&clause.u)) {
971991
if (const auto *name =
972992
std::get_if<Fortran::parser::Name>(&bindClause->v.u)) {
973993
if (Symbol *sym = ResolveFctName(*name)) {
974-
info.set_bindName(sym->name().ToString());
994+
if (info.deviceTypeInfos().empty()) {
995+
info.set_bindName(sym->name().ToString());
996+
} else {
997+
info.deviceTypeInfos().back().set_bindName(
998+
sym->name().ToString());
999+
}
9751000
} else {
9761001
context_.Say((*name).source,
9771002
"No function or subroutine declared for '%s'"_err_en_US,
@@ -986,8 +1011,19 @@ void AccAttributeVisitor::AddRoutineInfoToSymbol(
9861011
std::string str{std::get<std::string>(charConst->t)};
9871012
std::stringstream bindName;
9881013
bindName << "\"" << str << "\"";
989-
info.set_bindName(bindName.str());
1014+
if (info.deviceTypeInfos().empty()) {
1015+
info.set_bindName(bindName.str());
1016+
} else {
1017+
info.deviceTypeInfos().back().set_bindName(bindName.str());
1018+
}
9901019
}
1020+
} else if (const auto *dType =
1021+
std::get_if<Fortran::parser::AccClause::DeviceType>(
1022+
&clause.u)) {
1023+
const parser::AccDeviceTypeExprList &deviceTypeExprList = dType->v;
1024+
OpenACCRoutineDeviceTypeInfo dtypeInfo;
1025+
dtypeInfo.set_dType(deviceTypeExprList.v.front().v);
1026+
info.add_deviceTypeInfo(dtypeInfo);
9911027
}
9921028
}
9931029
symbol.get<SubprogramDetails>().add_openACCRoutineInfo(info);

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ subroutine sub9()
6060
subroutine sub10()
6161
end subroutine
6262

63+
subroutine sub11()
64+
!$acc routine device_type(nvidia) gang device_type(*) seq
65+
end subroutine
66+
67+
subroutine sub12()
68+
!$acc routine device_type(host) bind(sub7) device_type(multicore) bind(sub8)
69+
end subroutine
6370
end module
6471

6572
!Expect: acc_mod.mod
@@ -107,4 +114,10 @@ subroutine sub10()
107114
! subroutine sub10()
108115
! !$acc routine seq
109116
! end
117+
! subroutinesub11()
118+
! !$acc routine device_type(nvidia) gang device_type(*) seq
119+
! end
120+
! subroutinesub12()
121+
! !$acc routine device_type(host) bind(sub7) device_type(multicore) bind(sub8)
122+
! end
110123
! end

0 commit comments

Comments
 (0)