diff options
author | Valentin Clement (バレンタイン クレメン) <clementval@gmail.com> | 2024-02-13 08:52:13 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-13 08:52:13 -0800 |
commit | d79c3c50c45f2bd0acc0269dbedde9ddeed2d50e (patch) | |
tree | 7873be99faef622615c0849fa108bc555f279806 | |
parent | f879ac0385d4c5f7b2b9f4807cd7bd4a78556c1c (diff) | |
download | llvm-d79c3c50c45f2bd0acc0269dbedde9ddeed2d50e.zip llvm-d79c3c50c45f2bd0acc0269dbedde9ddeed2d50e.tar.gz llvm-d79c3c50c45f2bd0acc0269dbedde9ddeed2d50e.tar.bz2 |
[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.
-rw-r--r-- | flang/include/flang/Optimizer/Dialect/FIRAttr.td | 12 | ||||
-rw-r--r-- | flang/include/flang/Optimizer/Dialect/FIROpsSupport.h | 5 | ||||
-rw-r--r-- | flang/lib/Lower/CallInterface.cpp | 45 | ||||
-rw-r--r-- | flang/lib/Optimizer/Dialect/FIRAttr.cpp | 3 | ||||
-rw-r--r-- | flang/test/Lower/CUDA/cuda-proc-attribute.cuf | 6 |
5 files changed, 64 insertions, 7 deletions
diff --git a/flang/include/flang/Optimizer/Dialect/FIRAttr.td b/flang/include/flang/Optimizer/Dialect/FIRAttr.td index 00e293e..3602c67 100644 --- a/flang/include/flang/Optimizer/Dialect/FIRAttr.td +++ b/flang/include/flang/Optimizer/Dialect/FIRAttr.td @@ -113,4 +113,16 @@ def fir_CUDAProcAttributeAttr : let assemblyFormat = [{ ```<` $value `>` }]; } +def fir_CUDALaunchBoundsAttr : fir_Attr<"CUDALaunchBounds"> { + let mnemonic = "launch_bounds"; + + let parameters = (ins + "mlir::IntegerAttr":$maxTPB, + "mlir::IntegerAttr":$minBPM, + OptionalParameter<"mlir::IntegerAttr">:$upperBoundClusterSize + ); + + let assemblyFormat = "`<` struct(params) `>`"; +} + #endif // FIR_DIALECT_FIR_ATTRS diff --git a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h index 6ac6a31..29fa57c 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h +++ b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h @@ -75,6 +75,11 @@ static constexpr llvm::StringRef getTargetAttrName() { return "fir.target"; } /// Attribute to mark Fortran entities with the CUDA attribute. static constexpr llvm::StringRef getCUDAAttrName() { return "fir.cuda_attr"; } +/// Attribute to carry CUDA launch_bounds values. +static constexpr llvm::StringRef getCUDALaunchBoundsAttrName() { + return "fir.cuda_launch_bounds"; +} + /// Attribute to mark that a function argument is a character dummy procedure. /// Character dummy procedure have special ABI constraints. static constexpr llvm::StringRef getCharacterProcedureDummyAttrName() { diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp index 41597c1..f990e0b 100644 --- a/flang/lib/Lower/CallInterface.cpp +++ b/flang/lib/Lower/CallInterface.cpp @@ -524,6 +524,43 @@ static void addSymbolAttribute(mlir::func::FuncOp func, mlir::StringAttr::get(&mlirContext, name)); } +static void +setCUDAAttributes(mlir::func::FuncOp func, + const Fortran::semantics::Symbol *sym, + std::optional<Fortran::evaluate::characteristics::Procedure> + characteristic) { + if (characteristic && characteristic->cudaSubprogramAttrs) { + func.getOperation()->setAttr( + fir::getCUDAAttrName(), + fir::getCUDAProcAttribute(func.getContext(), + *characteristic->cudaSubprogramAttrs)); + } + + if (sym) { + if (auto details = + sym->GetUltimate() + .detailsIf<Fortran::semantics::SubprogramDetails>()) { + if (!details->cudaLaunchBounds().empty()) { + assert(details->cudaLaunchBounds().size() >= 2 && + "expect at least 2 values"); + mlir::Type i64Ty = mlir::IntegerType::get(func.getContext(), 64); + auto maxTPBAttr = + mlir::IntegerAttr::get(i64Ty, details->cudaLaunchBounds()[0]); + auto minBPMAttr = + mlir::IntegerAttr::get(i64Ty, details->cudaLaunchBounds()[1]); + mlir::IntegerAttr ubAttr; + if (details->cudaLaunchBounds().size() > 2) + ubAttr = + mlir::IntegerAttr::get(i64Ty, details->cudaLaunchBounds()[2]); + func.getOperation()->setAttr( + fir::getCUDALaunchBoundsAttrName(), + fir::CUDALaunchBoundsAttr::get(func.getContext(), maxTPBAttr, + minBPMAttr, ubAttr)); + } + } + } +} + /// Declare drives the different actions to be performed while analyzing the /// signature and building/finding the mlir::func::FuncOp. template <typename T> @@ -559,12 +596,8 @@ void Fortran::lower::CallInterface<T>::declare() { if (!placeHolder.value().attributes.empty()) func.setArgAttrs(placeHolder.index(), placeHolder.value().attributes); side().setFuncAttrs(func); - } - if (characteristic && characteristic->cudaSubprogramAttrs) { - func.getOperation()->setAttr( - fir::getCUDAAttrName(), - fir::getCUDAProcAttribute(func.getContext(), - *characteristic->cudaSubprogramAttrs)); + + setCUDAAttributes(func, side().getProcedureSymbol(), characteristic); } } } diff --git a/flang/lib/Optimizer/Dialect/FIRAttr.cpp b/flang/lib/Optimizer/Dialect/FIRAttr.cpp index 8df7a6c..8d780e0 100644 --- a/flang/lib/Optimizer/Dialect/FIRAttr.cpp +++ b/flang/lib/Optimizer/Dialect/FIRAttr.cpp @@ -298,5 +298,6 @@ void fir::printFirAttribute(FIROpsDialect *dialect, mlir::Attribute attr, void FIROpsDialect::registerAttributes() { addAttributes<ClosedIntervalAttr, ExactTypeAttr, FortranVariableFlagsAttr, LowerBoundAttr, PointIntervalAttr, RealAttr, SubclassAttr, - UpperBoundAttr, CUDADataAttributeAttr, CUDAProcAttributeAttr>(); + UpperBoundAttr, CUDADataAttributeAttr, CUDAProcAttributeAttr, + CUDALaunchBoundsAttr>(); } diff --git a/flang/test/Lower/CUDA/cuda-proc-attribute.cuf b/flang/test/Lower/CUDA/cuda-proc-attribute.cuf index 0507310..9eb2b85 100644 --- a/flang/test/Lower/CUDA/cuda-proc-attribute.cuf +++ b/flang/test/Lower/CUDA/cuda-proc-attribute.cuf @@ -32,3 +32,9 @@ attributes(host) attributes(device) integer function fct_host_device; end attributes(device) attributes(host) integer function fct_device_host; end ! CHECK: func.func @_QPfct_device_host() -> i32 attributes {fir.cuda_attr = #fir.cuda_proc<host_device>} + +attributes(global) launch_bounds(1, 2) subroutine sub_lbounds1(); end +! 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>} + +attributes(global) launch_bounds(1, 2, 3) subroutine sub_lbounds2(); end +! 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>} |