[flang-commits] [flang] [flang][cuda] Add UNIFIED data attribute (PR #88171)
via flang-commits
flang-commits at lists.llvm.org
Tue Apr 9 11:01:41 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Valentin Clement (バレンタイン クレメン) (clementval)
<details>
<summary>Changes</summary>
Latest version of the specification introduced the `UNIFIED` attribute for data.
https://docs.nvidia.com/hpc-sdk/compilers/cuda-fortran-prog-guide/#cfref-var-attr-unified-data
This patch adds the attribute to parsing, semantic and lowering.
The matching rules for dummy/actual argument is not part of of this patch.
---
Full diff: https://github.com/llvm/llvm-project/pull/88171.diff
7 Files Affected:
- (modified) flang/include/flang/Common/Fortran.h (+2-1)
- (modified) flang/include/flang/Optimizer/Support/Utils.h (+3)
- (modified) flang/include/flang/Parser/parse-tree.h (+1-1)
- (modified) flang/lib/Parser/Fortran-parsers.cpp (+4-2)
- (modified) flang/lib/Semantics/check-declarations.cpp (+7)
- (modified) flang/test/Lower/CUDA/cuda-data-attribute.cuf (+11)
- (modified) flang/test/Semantics/cuf03.cuf (+17)
``````````diff
diff --git a/flang/include/flang/Common/Fortran.h b/flang/include/flang/Common/Fortran.h
index ac1973fdff667a..2a53452a2774ff 100644
--- a/flang/include/flang/Common/Fortran.h
+++ b/flang/include/flang/Common/Fortran.h
@@ -85,7 +85,8 @@ static constexpr int maxRank{15};
ENUM_CLASS(CUDASubprogramAttrs, Host, Device, HostDevice, Global, Grid_Global)
// CUDA data attributes; mutually exclusive
-ENUM_CLASS(CUDADataAttr, Constant, Device, Managed, Pinned, Shared, Texture)
+ENUM_CLASS(
+ CUDADataAttr, Constant, Device, Managed, Pinned, Shared, Texture, Unified)
// OpenACC device types
ENUM_CLASS(
diff --git a/flang/include/flang/Optimizer/Support/Utils.h b/flang/include/flang/Optimizer/Support/Utils.h
index 7a8a34c25ce95c..2b4fa50e0e4217 100644
--- a/flang/include/flang/Optimizer/Support/Utils.h
+++ b/flang/include/flang/Optimizer/Support/Utils.h
@@ -158,6 +158,9 @@ getCUDADataAttribute(mlir::MLIRContext *mlirContext,
case Fortran::common::CUDADataAttr::Texture:
// Obsolete attribute
return {};
+ case Fortran::common::CUDADataAttr::Unified:
+ attr = fir::CUDADataAttribute::Unified;
+ break;
}
return fir::CUDADataAttributeAttr::get(mlirContext, attr);
}
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 26b2e5f4e34b06..ed2060b9e21144 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -991,7 +991,7 @@ struct ComponentArraySpec {
// access-spec | ALLOCATABLE |
// CODIMENSION lbracket coarray-spec rbracket |
// CONTIGUOUS | DIMENSION ( component-array-spec ) | POINTER |
-// (CUDA) CONSTANT | DEVICE | MANAGED | PINNED | SHARED | TEXTURE
+// (CUDA) CONSTANT | DEVICE | MANAGED | PINNED | SHARED | TEXTURE | UNIFIED
EMPTY_CLASS(Allocatable);
EMPTY_CLASS(Pointer);
EMPTY_CLASS(Contiguous);
diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp
index 21185694227d98..b4a1ed458079e1 100644
--- a/flang/lib/Parser/Fortran-parsers.cpp
+++ b/flang/lib/Parser/Fortran-parsers.cpp
@@ -702,13 +702,15 @@ TYPE_PARSER(construct<AttrSpec>(accessSpec) ||
extension<LanguageFeature::CUDA>(
construct<AttrSpec>(Parser<common::CUDADataAttr>{})))
-// CUDA-data-attr -> CONSTANT | DEVICE | MANAGED | PINNED | SHARED | TEXTURE
+// CUDA-data-attr ->
+// CONSTANT | DEVICE | MANAGED | PINNED | SHARED | TEXTURE | UNIFIED
TYPE_PARSER("CONSTANT" >> pure(common::CUDADataAttr::Constant) ||
"DEVICE" >> pure(common::CUDADataAttr::Device) ||
"MANAGED" >> pure(common::CUDADataAttr::Managed) ||
"PINNED" >> pure(common::CUDADataAttr::Pinned) ||
"SHARED" >> pure(common::CUDADataAttr::Shared) ||
- "TEXTURE" >> pure(common::CUDADataAttr::Texture))
+ "TEXTURE" >> pure(common::CUDADataAttr::Texture) ||
+ "UNIFIED" >> pure(common::CUDADataAttr::Unified))
// R804 object-name -> name
constexpr auto objectName{name};
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index b2de37759a0613..824f1b6053ca39 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -988,6 +988,13 @@ void CheckHelper::CheckObjectEntity(
symbol.name());
}
break;
+ case common::CUDADataAttr::Unified:
+ if ((!subpDetails || inDeviceSubprogram) && !isComponent) {
+ messages_.Say(
+ "Object '%s' with ATTRIBUTES(UNIFIED) must be declared in a host subprogram"_err_en_US,
+ symbol.name());
+ }
+ break;
case common::CUDADataAttr::Texture:
messages_.Say(
"ATTRIBUTES(TEXTURE) is obsolete and no longer supported"_err_en_US);
diff --git a/flang/test/Lower/CUDA/cuda-data-attribute.cuf b/flang/test/Lower/CUDA/cuda-data-attribute.cuf
index 94aa62352c2a0b..937c981bddd368 100644
--- a/flang/test/Lower/CUDA/cuda-data-attribute.cuf
+++ b/flang/test/Lower/CUDA/cuda-data-attribute.cuf
@@ -19,16 +19,20 @@ subroutine local_var_attrs
real, device :: rd
real, allocatable, managed :: rm
real, allocatable, pinned :: rp
+ real, unified :: ru
end subroutine
! CHECK-LABEL: func.func @_QMcuda_varPlocal_var_attrs()
! CHECK: %{{.*}}:2 = hlfir.declare %{{.*}} {cuda_attr = #fir.cuda<device>, uniq_name = "_QMcuda_varFlocal_var_attrsErd"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
! CHECK: %{{.*}}:2 = hlfir.declare %{{.*}} {cuda_attr = #fir.cuda<managed>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMcuda_varFlocal_var_attrsErm"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>)
! CHECK: %{{.*}}:2 = hlfir.declare %{{.*}} {cuda_attr = #fir.cuda<pinned>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMcuda_varFlocal_var_attrsErp"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>)
+! CHECK: %{{.*}}:2 = hlfir.declare %{{.*}} {cuda_attr = #fir.cuda<unified>, uniq_name = "_QMcuda_varFlocal_var_attrsEru"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+
! FIR: %{{.*}} = fir.declare %{{.*}} {cuda_attr = #fir.cuda<device>, uniq_name = "_QMcuda_varFlocal_var_attrsErd"} : (!fir.ref<f32>) -> !fir.ref<f32>
! FIR: %{{.*}} = fir.declare %{{.*}} {cuda_attr = #fir.cuda<managed>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMcuda_varFlocal_var_attrsErm"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>
! FIR: %{{.*}} = fir.declare %{{.*}} {cuda_attr = #fir.cuda<pinned>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMcuda_varFlocal_var_attrsErp"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>
+! FIR: %{{.*}} = fir.declare %{{.*}} {cuda_attr = #fir.cuda<unified>, uniq_name = "_QMcuda_varFlocal_var_attrsEru"} : (!fir.ref<f32>) -> !fir.ref<f32>
subroutine dummy_arg_device(dd)
real, device :: dd
@@ -51,4 +55,11 @@ end subroutine
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<f32>>> {fir.bindc_name = "dp", fir.cuda_attr = #fir.cuda<pinned>}) {
! CHECK: %{{.*}}:2 = hlfir.declare %[[ARG0]] {cuda_attr = #fir.cuda<pinned>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMcuda_varFdummy_arg_pinnedEdp"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>)
+subroutine dummy_arg_unified(du)
+ real, unified :: du
+end subroutine
+! CHECK-LABEL: func.func @_QMcuda_varPdummy_arg_unified(
+! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<f32> {fir.bindc_name = "du", fir.cuda_attr = #fir.cuda<unified>})
+! CHECK: %{{.*}}:2 = hlfir.declare %[[ARG0]] {cuda_attr = #fir.cuda<unified>, uniq_name = "_QMcuda_varFdummy_arg_unifiedEdu"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+
end module
diff --git a/flang/test/Semantics/cuf03.cuf b/flang/test/Semantics/cuf03.cuf
index 7384a104831d8d..574add9faaade7 100644
--- a/flang/test/Semantics/cuf03.cuf
+++ b/flang/test/Semantics/cuf03.cuf
@@ -1,6 +1,12 @@
! RUN: %python %S/test_errors.py %s %flang_fc1
! Exercise CUDA data attribute checks
module m
+ type :: t1
+ integer :: i
+ end type
+ type :: t2
+ real, unified :: r(10) ! ok
+ end type
real, constant :: mc ! ok
real, constant :: mci = 1. ! ok
!ERROR: Object 'mcl' with ATTRIBUTES(CONSTANT) may not be allocatable, pointer, or target
@@ -48,6 +54,9 @@ module m
real, texture, pointer :: mt
!ERROR: 'bigint' has intrinsic type 'INTEGER(16)' that is not available on the device
integer(16), device :: bigint
+ !ERROR: Object 'um' with ATTRIBUTES(UNIFIED) must be declared in a host subprogram
+ real, unified :: um
+
contains
attributes(device) subroutine devsubr(n,da)
integer, intent(in) :: n
@@ -57,6 +66,8 @@ module m
!WARNING: Pointer 'dp' may not be associated in a device subprogram
real, device, pointer :: dp
real, constant :: rc ! ok
+ !ERROR: Object 'u' with ATTRIBUTES(UNIFIED) must be declared in a host subprogram
+ real, unified :: u
end subroutine
subroutine host()
@@ -70,4 +81,10 @@ module m
rs = 1 ! ok
end subroutine
+ subroutine host2()
+ real, unified :: ru ! ok
+ type(t1), unified :: tu ! ok
+ type(t2) :: t ! ok
+ end subroutine
+
end module
``````````
</details>
https://github.com/llvm/llvm-project/pull/88171
More information about the flang-commits
mailing list