-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang][cuda] Add UNIFIED data attribute #88171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-flang-semantics @llvm/pr-subscribers-flang-fir-hlfir Author: Valentin Clement (バレンタイン クレメン) (clementval) ChangesLatest version of the specification introduced the 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:
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
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really well done; thanks!
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 arguments is not part of this patch.