Skip to content

Commit 9ec6c5d

Browse files
authored
[flang][cuda] Add fir.deallocate operation (#88839)
Add the fir.cuda_deallocate operation that perform device deallocation of data hold by a descriptor. This will replace the call to AllocatableDeallocate from the runtime. This is a companion operation to the one added in #88586
1 parent 377a276 commit 9ec6c5d

File tree

4 files changed

+81
-0
lines changed

4 files changed

+81
-0
lines changed

flang/include/flang/Optimizer/Dialect/FIROps.td

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3222,4 +3222,29 @@ def fir_CUDAAllocateOp : fir_Op<"cuda_allocate", [AttrSizedOperandSegments,
32223222
let hasVerifier = 1;
32233223
}
32243224

3225+
def fir_CUDADeallocateOp : fir_Op<"cuda_deallocate",
3226+
[MemoryEffects<[MemFree<DefaultResource>]>]> {
3227+
let summary = "Perform the device deallocation of data of an allocatable";
3228+
3229+
let description = [{
3230+
The fir.cuda_deallocate operation performs the deallocation on the device
3231+
of the data of an allocatable.
3232+
}];
3233+
3234+
let arguments = (ins Arg<fir_ReferenceType, "", [MemRead, MemWrite]>:$box,
3235+
Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg,
3236+
fir_CUDADataAttributeAttr:$cuda_attr,
3237+
UnitAttr:$hasStat);
3238+
3239+
let results = (outs AnyIntegerType:$stat);
3240+
3241+
let assemblyFormat = [{
3242+
$box `:` qualified(type($box))
3243+
( `errmsg` `(` $errmsg^ `:` type($errmsg) `)` )?
3244+
attr-dict `->` type($stat)
3245+
}];
3246+
3247+
let hasVerifier = 1;
3248+
}
3249+
32253250
#endif

flang/lib/Optimizer/Dialect/FIROps.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4012,6 +4012,19 @@ mlir::LogicalResult fir::CUDAAllocateOp::verify() {
40124012
return mlir::success();
40134013
}
40144014

4015+
mlir::LogicalResult fir::CUDADeallocateOp::verify() {
4016+
if (!fir::unwrapRefType(getBox().getType()).isa<fir::BaseBoxType>())
4017+
return emitOpError(
4018+
"expect box to be a reference to class or box type value");
4019+
if (getErrmsg() &&
4020+
!fir::unwrapRefType(getErrmsg().getType()).isa<fir::BoxType>())
4021+
return emitOpError(
4022+
"expect errmsg to be a reference to/or a box type value");
4023+
if (getErrmsg() && !getHasStat())
4024+
return emitOpError("expect stat attribute when errmsg is provided");
4025+
return mlir::success();
4026+
}
4027+
40154028
//===----------------------------------------------------------------------===//
40164029
// FIROpsDialect
40174030
//===----------------------------------------------------------------------===//

flang/test/Fir/cuf-invalid.fir

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,40 @@ func.func @_QPsub1() {
4848
%13 = fir.cuda_allocate %11 : !fir.ref<!fir.box<none>> errmsg(%1 : !fir.ref<i32>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32
4949
return
5050
}
51+
52+
// -----
53+
54+
func.func @_QPsub1() {
55+
%1 = fir.alloca i32
56+
// expected-error@+1{{'fir.cuda_deallocate' op expect box to be a reference to class or box type value}}
57+
%2 = fir.cuda_deallocate %1 : !fir.ref<i32> {cuda_attr = #fir.cuda<device>} -> i32
58+
return
59+
}
60+
61+
// -----
62+
63+
func.func @_QPsub1() {
64+
%0 = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a", uniq_name = "_QFsub1Ea"}
65+
%4:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
66+
%1 = fir.alloca i32
67+
%11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
68+
// expected-error@+1{{'fir.cuda_deallocate' op expect errmsg to be a reference to/or a box type value}}
69+
%13 = fir.cuda_deallocate %11 : !fir.ref<!fir.box<none>> errmsg(%1 : !fir.ref<i32>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32
70+
return
71+
}
72+
73+
// -----
74+
75+
func.func @_QPsub1() {
76+
%0 = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a", uniq_name = "_QFsub1Ea"}
77+
%4:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
78+
%c100 = arith.constant 100 : index
79+
%7 = fir.alloca !fir.char<1,100> {bindc_name = "msg", uniq_name = "_QFsub1Emsg"}
80+
%8:2 = hlfir.declare %7 typeparams %c100 {uniq_name = "_QFsub1Emsg"} : (!fir.ref<!fir.char<1,100>>, index) -> (!fir.ref<!fir.char<1,100>>, !fir.ref<!fir.char<1,100>>)
81+
%9 = fir.embox %8#1 : (!fir.ref<!fir.char<1,100>>) -> !fir.box<!fir.char<1,100>>
82+
%11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
83+
%16 = fir.convert %9 : (!fir.box<!fir.char<1,100>>) -> !fir.box<none>
84+
// expected-error@+1{{'fir.cuda_deallocate' op expect stat attribute when errmsg is provided}}
85+
%13 = fir.cuda_deallocate %11 : !fir.ref<!fir.box<none>> errmsg(%16 : !fir.box<none>) {cuda_attr = #fir.cuda<device>} -> i32
86+
return
87+
}

flang/test/Fir/cuf.mlir

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ func.func @_QPsub1() {
77
%4:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
88
%11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
99
%13 = fir.cuda_allocate %11 : !fir.ref<!fir.box<none>> {cuda_attr = #fir.cuda<device>} -> i32
10+
%14 = fir.cuda_deallocate %11 : !fir.ref<!fir.box<none>> {cuda_attr = #fir.cuda<device>} -> i32
1011
return
1112
}
1213

1314
// CHECK: fir.cuda_allocate %{{.*}} : !fir.ref<!fir.box<none>> {cuda_attr = #fir.cuda<device>} -> i32
15+
// CHECK: fir.cuda_deallocate %{{.*}} : !fir.ref<!fir.box<none>> {cuda_attr = #fir.cuda<device>} -> i32
1416

1517
// -----
1618

@@ -66,5 +68,9 @@ func.func @_QPsub1() {
6668
%11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
6769
%16 = fir.convert %9 : (!fir.box<!fir.char<1,100>>) -> !fir.box<none>
6870
%13 = fir.cuda_allocate %11 : !fir.ref<!fir.box<none>> errmsg(%16 : !fir.box<none>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32
71+
%14 = fir.cuda_deallocate %11 : !fir.ref<!fir.box<none>> errmsg(%16 : !fir.box<none>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32
6972
return
7073
}
74+
75+
// CHECK: fir.cuda_allocate %{{.*}} : !fir.ref<!fir.box<none>> errmsg(%{{.*}} : !fir.box<none>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32
76+
// CHECK: fir.cuda_deallocate %{{.*}} : !fir.ref<!fir.box<none>> errmsg(%{{.*}} : !fir.box<none>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32

0 commit comments

Comments
 (0)