Skip to content

Commit 2263210

Browse files
[mlir][acc] Add destroy region to reduction recipes (#155480)
Reduction recipes capture how a private copy is created. In some languages, like C++ class variables with destructors - that private copy also must be properly destroyed. Thus update the reduction recipe to contain a `destroy` region similarly to the private recipes.
1 parent d66b537 commit 2263210

File tree

2 files changed

+74
-2
lines changed

2 files changed

+74
-2
lines changed

mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,7 +1302,7 @@ def OpenACC_ReductionRecipeOp
13021302

13031303
let description = [{
13041304
Declares an OpenACC reduction recipe. The operation requires two
1305-
mandatory regions.
1305+
mandatory regions and one optional region.
13061306

13071307
1. The initializer region specifies how to initialize the local reduction
13081308
value. The region has a first argument that contains the value of the
@@ -1313,6 +1313,8 @@ def OpenACC_ReductionRecipeOp
13131313
values of the reduction type into one. It has at least two arguments
13141314
and it is expected to `acc.yield` the combined value. Extra arguments
13151315
can be added to deal with dynamic arrays.
1316+
3. The optional destroy region specifies how to destruct the value when it
1317+
reaches its end of life. It takes the reduction value as argument.
13161318

13171319
Example:
13181320

@@ -1329,6 +1331,10 @@ def OpenACC_ReductionRecipeOp
13291331
// two values into one.
13301332
%2 = arith.addi %0, %1 : i64
13311333
acc.yield %2 : i64
1334+
} destroy {
1335+
^bb0(%0: i64)
1336+
// destroy region contains a sequence of operations to destruct the
1337+
// created copy.
13321338
}
13331339

13341340
// The reduction symbol is then used in the corresponding operation.
@@ -1362,12 +1368,14 @@ def OpenACC_ReductionRecipeOp
13621368
OpenACC_ReductionOperatorAttr:$reductionOperator);
13631369

13641370
let regions = (region AnyRegion:$initRegion,
1365-
AnyRegion:$combinerRegion);
1371+
AnyRegion:$combinerRegion,
1372+
AnyRegion:$destroyRegion);
13661373

13671374
let assemblyFormat = [{
13681375
$sym_name `:` $type attr-dict-with-keyword
13691376
`reduction_operator` $reductionOperator
13701377
`init` $initRegion `combiner` $combinerRegion
1378+
(`destroy` $destroyRegion^)?
13711379
}];
13721380

13731381
let hasRegionVerifier = 1;

mlir/test/Dialect/OpenACC/ops.mlir

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1954,6 +1954,70 @@ acc.reduction.recipe @reduction_add_memref_i32 : memref<i32> reduction_operator
19541954
// CHECK-LABEL: acc.reduction.recipe @reduction_add_memref_i32
19551955
// CHECK: memref.alloca
19561956

1957+
// -----
1958+
1959+
// Test reduction recipe with destroy region using dynamic memory allocation
1960+
acc.reduction.recipe @reduction_add_with_destroy : memref<?xf32> reduction_operator<add> init {
1961+
^bb0(%arg0: memref<?xf32>):
1962+
%cst = arith.constant 0.000000e+00 : f32
1963+
%c0 = arith.constant 0 : index
1964+
%size = memref.dim %arg0, %c0 : memref<?xf32>
1965+
%alloc = memref.alloc(%size) : memref<?xf32>
1966+
%c1 = arith.constant 1 : index
1967+
scf.for %i = %c0 to %size step %c1 {
1968+
memref.store %cst, %alloc[%i] : memref<?xf32>
1969+
}
1970+
acc.yield %alloc : memref<?xf32>
1971+
} combiner {
1972+
^bb0(%arg0: memref<?xf32>, %arg1: memref<?xf32>):
1973+
%c0 = arith.constant 0 : index
1974+
%c1 = arith.constant 1 : index
1975+
%size = memref.dim %arg0, %c0 : memref<?xf32>
1976+
scf.for %i = %c0 to %size step %c1 {
1977+
%val0 = memref.load %arg0[%i] : memref<?xf32>
1978+
%val1 = memref.load %arg1[%i] : memref<?xf32>
1979+
%sum = arith.addf %val0, %val1 : f32
1980+
memref.store %sum, %arg0[%i] : memref<?xf32>
1981+
}
1982+
acc.yield %arg0 : memref<?xf32>
1983+
} destroy {
1984+
^bb0(%arg0: memref<?xf32>):
1985+
// destroy region to deallocate dynamically allocated memory
1986+
memref.dealloc %arg0 : memref<?xf32>
1987+
acc.yield
1988+
}
1989+
1990+
// CHECK-LABEL: acc.reduction.recipe @reduction_add_with_destroy : memref<?xf32> reduction_operator <add> init {
1991+
// CHECK: ^bb0(%[[ARG:.*]]: memref<?xf32>):
1992+
// CHECK: %[[CST:.*]] = arith.constant 0.000000e+00 : f32
1993+
// CHECK: %[[C0:.*]] = arith.constant 0 : index
1994+
// CHECK: %[[SIZE:.*]] = memref.dim %[[ARG]], %[[C0]] : memref<?xf32>
1995+
// CHECK: %[[ALLOC:.*]] = memref.alloc(%[[SIZE]]) : memref<?xf32>
1996+
// CHECK: %[[C1:.*]] = arith.constant 1 : index
1997+
// CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[SIZE]] step %[[C1]] {
1998+
// CHECK: memref.store %[[CST]], %[[ALLOC]][%[[I]]] : memref<?xf32>
1999+
// CHECK: }
2000+
// CHECK: acc.yield %[[ALLOC]] : memref<?xf32>
2001+
// CHECK: } combiner {
2002+
// CHECK: ^bb0(%[[ARG0:.*]]: memref<?xf32>, %[[ARG1:.*]]: memref<?xf32>):
2003+
// CHECK: %[[C0_1:.*]] = arith.constant 0 : index
2004+
// CHECK: %[[C1_1:.*]] = arith.constant 1 : index
2005+
// CHECK: %[[SIZE_1:.*]] = memref.dim %[[ARG0]], %[[C0_1]] : memref<?xf32>
2006+
// CHECK: scf.for %[[I_1:.*]] = %[[C0_1]] to %[[SIZE_1]] step %[[C1_1]] {
2007+
// CHECK: %{{.*}} = memref.load %[[ARG0]][%[[I_1]]] : memref<?xf32>
2008+
// CHECK: %{{.*}} = memref.load %[[ARG1]][%[[I_1]]] : memref<?xf32>
2009+
// CHECK: %[[SUM:.*]] = arith.addf %{{.*}}, %{{.*}} : f32
2010+
// CHECK: memref.store %[[SUM]], %[[ARG0]][%[[I_1]]] : memref<?xf32>
2011+
// CHECK: }
2012+
// CHECK: acc.yield %[[ARG0]] : memref<?xf32>
2013+
// CHECK: } destroy {
2014+
// CHECK: ^bb0(%[[ARG_DESTROY:.*]]: memref<?xf32>):
2015+
// CHECK: memref.dealloc %[[ARG_DESTROY]] : memref<?xf32>
2016+
// CHECK: acc.yield
2017+
// CHECK: }
2018+
2019+
// -----
2020+
19572021
acc.private.recipe @privatization_memref_i32 : memref<i32> init {
19582022
^bb0(%arg0: memref<i32>):
19592023
%alloca = memref.alloca() : memref<i32>

0 commit comments

Comments
 (0)