Skip to content

[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

Merged
merged 1 commit into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion flang/include/flang/Common/Fortran.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
3 changes: 3 additions & 0 deletions flang/include/flang/Optimizer/Support/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 4 additions & 2 deletions flang/lib/Parser/Fortran-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
7 changes: 7 additions & 0 deletions flang/lib/Semantics/check-declarations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
11 changes: 11 additions & 0 deletions flang/test/Lower/CUDA/cuda-data-attribute.cuf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
17 changes: 17 additions & 0 deletions flang/test/Semantics/cuf03.cuf
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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()
Expand All @@ -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