Skip to content

Commit e953c86

Browse files
authored
[flang][cuda] Add UNIFIED data attribute (#88171)
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.
1 parent a8ec1eb commit e953c86

File tree

7 files changed

+45
-4
lines changed

7 files changed

+45
-4
lines changed

flang/include/flang/Common/Fortran.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ static constexpr int maxRank{15};
8585
ENUM_CLASS(CUDASubprogramAttrs, Host, Device, HostDevice, Global, Grid_Global)
8686

8787
// CUDA data attributes; mutually exclusive
88-
ENUM_CLASS(CUDADataAttr, Constant, Device, Managed, Pinned, Shared, Texture)
88+
ENUM_CLASS(
89+
CUDADataAttr, Constant, Device, Managed, Pinned, Shared, Texture, Unified)
8990

9091
// OpenACC device types
9192
ENUM_CLASS(

flang/include/flang/Optimizer/Support/Utils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ getCUDADataAttribute(mlir::MLIRContext *mlirContext,
158158
case Fortran::common::CUDADataAttr::Texture:
159159
// Obsolete attribute
160160
return {};
161+
case Fortran::common::CUDADataAttr::Unified:
162+
attr = fir::CUDADataAttribute::Unified;
163+
break;
161164
}
162165
return fir::CUDADataAttributeAttr::get(mlirContext, attr);
163166
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,7 @@ struct ComponentArraySpec {
991991
// access-spec | ALLOCATABLE |
992992
// CODIMENSION lbracket coarray-spec rbracket |
993993
// CONTIGUOUS | DIMENSION ( component-array-spec ) | POINTER |
994-
// (CUDA) CONSTANT | DEVICE | MANAGED | PINNED | SHARED | TEXTURE
994+
// (CUDA) CONSTANT | DEVICE | MANAGED | PINNED | SHARED | TEXTURE | UNIFIED
995995
EMPTY_CLASS(Allocatable);
996996
EMPTY_CLASS(Pointer);
997997
EMPTY_CLASS(Contiguous);

flang/lib/Parser/Fortran-parsers.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -703,13 +703,15 @@ TYPE_PARSER(construct<AttrSpec>(accessSpec) ||
703703
extension<LanguageFeature::CUDA>(
704704
construct<AttrSpec>(Parser<common::CUDADataAttr>{})))
705705

706-
// CUDA-data-attr -> CONSTANT | DEVICE | MANAGED | PINNED | SHARED | TEXTURE
706+
// CUDA-data-attr ->
707+
// CONSTANT | DEVICE | MANAGED | PINNED | SHARED | TEXTURE | UNIFIED
707708
TYPE_PARSER("CONSTANT" >> pure(common::CUDADataAttr::Constant) ||
708709
"DEVICE" >> pure(common::CUDADataAttr::Device) ||
709710
"MANAGED" >> pure(common::CUDADataAttr::Managed) ||
710711
"PINNED" >> pure(common::CUDADataAttr::Pinned) ||
711712
"SHARED" >> pure(common::CUDADataAttr::Shared) ||
712-
"TEXTURE" >> pure(common::CUDADataAttr::Texture))
713+
"TEXTURE" >> pure(common::CUDADataAttr::Texture) ||
714+
"UNIFIED" >> pure(common::CUDADataAttr::Unified))
713715

714716
// R804 object-name -> name
715717
constexpr auto objectName{name};

flang/lib/Semantics/check-declarations.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,13 @@ void CheckHelper::CheckObjectEntity(
988988
symbol.name());
989989
}
990990
break;
991+
case common::CUDADataAttr::Unified:
992+
if ((!subpDetails || inDeviceSubprogram) && !isComponent) {
993+
messages_.Say(
994+
"Object '%s' with ATTRIBUTES(UNIFIED) must be declared in a host subprogram"_err_en_US,
995+
symbol.name());
996+
}
997+
break;
991998
case common::CUDADataAttr::Texture:
992999
messages_.Say(
9931000
"ATTRIBUTES(TEXTURE) is obsolete and no longer supported"_err_en_US);

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,20 @@ subroutine local_var_attrs
1919
real, device :: rd
2020
real, allocatable, managed :: rm
2121
real, allocatable, pinned :: rp
22+
real, unified :: ru
2223
end subroutine
2324

2425
! CHECK-LABEL: func.func @_QMcuda_varPlocal_var_attrs()
2526
! CHECK: %{{.*}}:2 = hlfir.declare %{{.*}} {cuda_attr = #fir.cuda<device>, uniq_name = "_QMcuda_varFlocal_var_attrsErd"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
2627
! 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>>>)
2728
! 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>>>)
29+
! CHECK: %{{.*}}:2 = hlfir.declare %{{.*}} {cuda_attr = #fir.cuda<unified>, uniq_name = "_QMcuda_varFlocal_var_attrsEru"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
30+
2831

2932
! FIR: %{{.*}} = fir.declare %{{.*}} {cuda_attr = #fir.cuda<device>, uniq_name = "_QMcuda_varFlocal_var_attrsErd"} : (!fir.ref<f32>) -> !fir.ref<f32>
3033
! 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>>>
3134
! 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>>>
35+
! FIR: %{{.*}} = fir.declare %{{.*}} {cuda_attr = #fir.cuda<unified>, uniq_name = "_QMcuda_varFlocal_var_attrsEru"} : (!fir.ref<f32>) -> !fir.ref<f32>
3236

3337
subroutine dummy_arg_device(dd)
3438
real, device :: dd
@@ -51,4 +55,11 @@ end subroutine
5155
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<f32>>> {fir.bindc_name = "dp", fir.cuda_attr = #fir.cuda<pinned>}) {
5256
! 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>>>)
5357

58+
subroutine dummy_arg_unified(du)
59+
real, unified :: du
60+
end subroutine
61+
! CHECK-LABEL: func.func @_QMcuda_varPdummy_arg_unified(
62+
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<f32> {fir.bindc_name = "du", fir.cuda_attr = #fir.cuda<unified>})
63+
! 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>)
64+
5465
end module

flang/test/Semantics/cuf03.cuf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
! RUN: %python %S/test_errors.py %s %flang_fc1
22
! Exercise CUDA data attribute checks
33
module m
4+
type :: t1
5+
integer :: i
6+
end type
7+
type :: t2
8+
real, unified :: r(10) ! ok
9+
end type
410
real, constant :: mc ! ok
511
real, constant :: mci = 1. ! ok
612
!ERROR: Object 'mcl' with ATTRIBUTES(CONSTANT) may not be allocatable, pointer, or target
@@ -48,6 +54,9 @@ module m
4854
real, texture, pointer :: mt
4955
!ERROR: 'bigint' has intrinsic type 'INTEGER(16)' that is not available on the device
5056
integer(16), device :: bigint
57+
!ERROR: Object 'um' with ATTRIBUTES(UNIFIED) must be declared in a host subprogram
58+
real, unified :: um
59+
5160
contains
5261
attributes(device) subroutine devsubr(n,da)
5362
integer, intent(in) :: n
@@ -57,6 +66,8 @@ module m
5766
!WARNING: Pointer 'dp' may not be associated in a device subprogram
5867
real, device, pointer :: dp
5968
real, constant :: rc ! ok
69+
!ERROR: Object 'u' with ATTRIBUTES(UNIFIED) must be declared in a host subprogram
70+
real, unified :: u
6071
end subroutine
6172

6273
subroutine host()
@@ -70,4 +81,10 @@ module m
7081
rs = 1 ! ok
7182
end subroutine
7283

84+
subroutine host2()
85+
real, unified :: ru ! ok
86+
type(t1), unified :: tu ! ok
87+
type(t2) :: t ! ok
88+
end subroutine
89+
7390
end module

0 commit comments

Comments
 (0)