Skip to content

Commit d79c3c5

Browse files
authored
[flang][cuda] Lower launch_bounds values (#81537)
This PR adds a new attribute to carry over the information from `launch_bounds`. The new attribute `CUDALaunchBoundsAttr` holds 2 to 3 integer attrinbutes and is added to `func.func` operation.
1 parent f879ac0 commit d79c3c5

File tree

5 files changed

+64
-7
lines changed

5 files changed

+64
-7
lines changed

flang/include/flang/Optimizer/Dialect/FIRAttr.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,16 @@ def fir_CUDAProcAttributeAttr :
113113
let assemblyFormat = [{ ```<` $value `>` }];
114114
}
115115

116+
def fir_CUDALaunchBoundsAttr : fir_Attr<"CUDALaunchBounds"> {
117+
let mnemonic = "launch_bounds";
118+
119+
let parameters = (ins
120+
"mlir::IntegerAttr":$maxTPB,
121+
"mlir::IntegerAttr":$minBPM,
122+
OptionalParameter<"mlir::IntegerAttr">:$upperBoundClusterSize
123+
);
124+
125+
let assemblyFormat = "`<` struct(params) `>`";
126+
}
127+
116128
#endif // FIR_DIALECT_FIR_ATTRS

flang/include/flang/Optimizer/Dialect/FIROpsSupport.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ static constexpr llvm::StringRef getTargetAttrName() { return "fir.target"; }
7575
/// Attribute to mark Fortran entities with the CUDA attribute.
7676
static constexpr llvm::StringRef getCUDAAttrName() { return "fir.cuda_attr"; }
7777

78+
/// Attribute to carry CUDA launch_bounds values.
79+
static constexpr llvm::StringRef getCUDALaunchBoundsAttrName() {
80+
return "fir.cuda_launch_bounds";
81+
}
82+
7883
/// Attribute to mark that a function argument is a character dummy procedure.
7984
/// Character dummy procedure have special ABI constraints.
8085
static constexpr llvm::StringRef getCharacterProcedureDummyAttrName() {

flang/lib/Lower/CallInterface.cpp

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,43 @@ static void addSymbolAttribute(mlir::func::FuncOp func,
524524
mlir::StringAttr::get(&mlirContext, name));
525525
}
526526

527+
static void
528+
setCUDAAttributes(mlir::func::FuncOp func,
529+
const Fortran::semantics::Symbol *sym,
530+
std::optional<Fortran::evaluate::characteristics::Procedure>
531+
characteristic) {
532+
if (characteristic && characteristic->cudaSubprogramAttrs) {
533+
func.getOperation()->setAttr(
534+
fir::getCUDAAttrName(),
535+
fir::getCUDAProcAttribute(func.getContext(),
536+
*characteristic->cudaSubprogramAttrs));
537+
}
538+
539+
if (sym) {
540+
if (auto details =
541+
sym->GetUltimate()
542+
.detailsIf<Fortran::semantics::SubprogramDetails>()) {
543+
if (!details->cudaLaunchBounds().empty()) {
544+
assert(details->cudaLaunchBounds().size() >= 2 &&
545+
"expect at least 2 values");
546+
mlir::Type i64Ty = mlir::IntegerType::get(func.getContext(), 64);
547+
auto maxTPBAttr =
548+
mlir::IntegerAttr::get(i64Ty, details->cudaLaunchBounds()[0]);
549+
auto minBPMAttr =
550+
mlir::IntegerAttr::get(i64Ty, details->cudaLaunchBounds()[1]);
551+
mlir::IntegerAttr ubAttr;
552+
if (details->cudaLaunchBounds().size() > 2)
553+
ubAttr =
554+
mlir::IntegerAttr::get(i64Ty, details->cudaLaunchBounds()[2]);
555+
func.getOperation()->setAttr(
556+
fir::getCUDALaunchBoundsAttrName(),
557+
fir::CUDALaunchBoundsAttr::get(func.getContext(), maxTPBAttr,
558+
minBPMAttr, ubAttr));
559+
}
560+
}
561+
}
562+
}
563+
527564
/// Declare drives the different actions to be performed while analyzing the
528565
/// signature and building/finding the mlir::func::FuncOp.
529566
template <typename T>
@@ -559,12 +596,8 @@ void Fortran::lower::CallInterface<T>::declare() {
559596
if (!placeHolder.value().attributes.empty())
560597
func.setArgAttrs(placeHolder.index(), placeHolder.value().attributes);
561598
side().setFuncAttrs(func);
562-
}
563-
if (characteristic && characteristic->cudaSubprogramAttrs) {
564-
func.getOperation()->setAttr(
565-
fir::getCUDAAttrName(),
566-
fir::getCUDAProcAttribute(func.getContext(),
567-
*characteristic->cudaSubprogramAttrs));
599+
600+
setCUDAAttributes(func, side().getProcedureSymbol(), characteristic);
568601
}
569602
}
570603
}

flang/lib/Optimizer/Dialect/FIRAttr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,5 +298,6 @@ void fir::printFirAttribute(FIROpsDialect *dialect, mlir::Attribute attr,
298298
void FIROpsDialect::registerAttributes() {
299299
addAttributes<ClosedIntervalAttr, ExactTypeAttr, FortranVariableFlagsAttr,
300300
LowerBoundAttr, PointIntervalAttr, RealAttr, SubclassAttr,
301-
UpperBoundAttr, CUDADataAttributeAttr, CUDAProcAttributeAttr>();
301+
UpperBoundAttr, CUDADataAttributeAttr, CUDAProcAttributeAttr,
302+
CUDALaunchBoundsAttr>();
302303
}

flang/test/Lower/CUDA/cuda-proc-attribute.cuf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,9 @@ attributes(host) attributes(device) integer function fct_host_device; end
3232

3333
attributes(device) attributes(host) integer function fct_device_host; end
3434
! CHECK: func.func @_QPfct_device_host() -> i32 attributes {fir.cuda_attr = #fir.cuda_proc<host_device>}
35+
36+
attributes(global) launch_bounds(1, 2) subroutine sub_lbounds1(); end
37+
! CHECK: func.func @_QPsub_lbounds1() attributes {fir.cuda_attr = #fir.cuda_proc<global>, fir.cuda_launch_bounds = #fir.launch_bounds<maxTPB = 1 : i64, minBPM = 2 : i64>}
38+
39+
attributes(global) launch_bounds(1, 2, 3) subroutine sub_lbounds2(); end
40+
! CHECK: func.func @_QPsub_lbounds2() attributes {fir.cuda_attr = #fir.cuda_proc<global>, fir.cuda_launch_bounds = #fir.launch_bounds<maxTPB = 1 : i64, minBPM = 2 : i64, upperBoundClusterSize = 3 : i64>}

0 commit comments

Comments
 (0)