Skip to content

Commit db1254d

Browse files
clementvalAntonRydahl
authored andcommitted
[mlir][openacc] Model acc cache directive as data entry operands on acc.loop (llvm#65521)
The `cache` directive may appear at the top of (inside of) a loop. It specifies array elements or subarrays that should be fetched into the highest level of the cache for the body of the loop. The `cache` directive is modeled as a data entry operands attached to the acc.loop operation.
1 parent 60c243a commit db1254d

File tree

5 files changed

+66
-20
lines changed

5 files changed

+66
-20
lines changed

flang/lib/Lower/OpenACC.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,8 +1356,8 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
13561356
mlir::Value gangNum;
13571357
mlir::Value gangDim;
13581358
mlir::Value gangStatic;
1359-
llvm::SmallVector<mlir::Value, 2> tileOperands, privateOperands,
1360-
reductionOperands;
1359+
llvm::SmallVector<mlir::Value> tileOperands, privateOperands,
1360+
reductionOperands, cacheOperands;
13611361
llvm::SmallVector<mlir::Attribute> privatizations, reductionRecipes;
13621362
bool hasGang = false, hasVector = false, hasWorker = false;
13631363

@@ -1451,6 +1451,7 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
14511451
addOperands(operands, operandSegments, tileOperands);
14521452
addOperands(operands, operandSegments, privateOperands);
14531453
addOperands(operands, operandSegments, reductionOperands);
1454+
addOperands(operands, operandSegments, cacheOperands);
14541455

14551456
auto loopOp = createRegionOp<mlir::acc::LoopOp, mlir::acc::YieldOp>(
14561457
builder, currentLocation, operands, operandSegments);

mlir/include/mlir/Dialect/OpenACC/OpenACC.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
mlir::acc::GetDevicePtrOp, mlir::acc::PrivateOp, \
4343
mlir::acc::FirstprivateOp, mlir::acc::UpdateDeviceOp, \
4444
mlir::acc::UseDeviceOp, mlir::acc::ReductionOp, \
45-
mlir::acc::DeclareDeviceResidentOp, mlir::acc::DeclareLinkOp
45+
mlir::acc::DeclareDeviceResidentOp, mlir::acc::DeclareLinkOp, \
46+
mlir::acc::CacheOp
4647
#define ACC_COMPUTE_CONSTRUCT_OPS \
4748
mlir::acc::ParallelOp, mlir::acc::KernelsOp, mlir::acc::SerialOp
4849
#define ACC_DATA_CONSTRUCT_OPS \

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

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ def OpenACC_UseDevice : I64EnumAttrCase<"acc_use_device", 20>;
9898
def OpenACC_Reduction : I64EnumAttrCase<"acc_reduction", 21>;
9999
def OpenACC_DeclareDeviceResident : I64EnumAttrCase<"acc_declare_device_resident", 22>;
100100
def OpenACC_DeclareLink : I64EnumAttrCase<"acc_declare_link", 23>;
101+
def OpenACC_Cache : I64EnumAttrCase<"acc_cache", 24>;
102+
def OpenACC_CacheReadonly : I64EnumAttrCase<"acc_cache_readonly", 25>;
101103

102104
def OpenACC_DataClauseEnum : I64EnumAttr<"DataClause",
103105
"data clauses supported by OpenACC",
@@ -109,6 +111,7 @@ def OpenACC_DataClauseEnum : I64EnumAttr<"DataClause",
109111
OpenACC_IsDevicePtrClause, OpenACC_GetDevicePtrClause, OpenACC_UpdateHost,
110112
OpenACC_UpdateSelf, OpenACC_UpdateDevice, OpenACC_UseDevice,
111113
OpenACC_Reduction, OpenACC_DeclareDeviceResident, OpenACC_DeclareLink,
114+
OpenACC_Cache, OpenACC_CacheReadonly,
112115
]> {
113116
let cppNamespace = "::mlir::acc";
114117
let genSpecializedAttr = 0;
@@ -406,6 +409,22 @@ def OpenACC_DeclareLinkOp : OpenACC_DataEntryOp<"declare_link",
406409
let summary = "Represents acc declare link semantics.";
407410
}
408411

412+
//===----------------------------------------------------------------------===//
413+
// 2.10 cache directive
414+
//===----------------------------------------------------------------------===//
415+
def OpenACC_CacheOp : OpenACC_DataEntryOp<"cache",
416+
"mlir::acc::DataClause::acc_cache", ""> {
417+
let summary = "Represents the cache directive that is associated with a "
418+
"loop.";
419+
420+
let extraClassDeclaration = [{
421+
/// Check if this is a cache with readonly modifier.
422+
bool isCacheReadonly() {
423+
return getDataClause() == acc::DataClause::acc_cache_readonly;
424+
}
425+
}];
426+
}
427+
409428
// Data exit operation does not refer to OpenACC spec terminology, but to
410429
// terminology used in this dialect. It refers to data operations that will appear
411430
// after data or compute region. It will be used as the base of acc dialect
@@ -1140,22 +1159,23 @@ def OpenACC_LoopOp : OpenACC_Op<"loop",
11401159
}];
11411160

11421161
let arguments = (ins OptionalAttr<I64Attr>:$collapse,
1143-
Optional<IntOrIndex>:$gangNum,
1144-
Optional<IntOrIndex>:$gangDim,
1145-
Optional<IntOrIndex>:$gangStatic,
1146-
Optional<IntOrIndex>:$workerNum,
1147-
Optional<IntOrIndex>:$vectorLength,
1148-
UnitAttr:$seq,
1149-
UnitAttr:$independent,
1150-
UnitAttr:$auto_,
1151-
UnitAttr:$hasGang,
1152-
UnitAttr:$hasWorker,
1153-
UnitAttr:$hasVector,
1154-
Variadic<IntOrIndex>:$tileOperands,
1155-
Variadic<OpenACC_PointerLikeTypeInterface>:$privateOperands,
1156-
OptionalAttr<SymbolRefArrayAttr>:$privatizations,
1157-
Variadic<AnyType>:$reductionOperands,
1158-
OptionalAttr<SymbolRefArrayAttr>:$reductionRecipes);
1162+
Optional<IntOrIndex>:$gangNum,
1163+
Optional<IntOrIndex>:$gangDim,
1164+
Optional<IntOrIndex>:$gangStatic,
1165+
Optional<IntOrIndex>:$workerNum,
1166+
Optional<IntOrIndex>:$vectorLength,
1167+
UnitAttr:$seq,
1168+
UnitAttr:$independent,
1169+
UnitAttr:$auto_,
1170+
UnitAttr:$hasGang,
1171+
UnitAttr:$hasWorker,
1172+
UnitAttr:$hasVector,
1173+
Variadic<IntOrIndex>:$tileOperands,
1174+
Variadic<OpenACC_PointerLikeTypeInterface>:$privateOperands,
1175+
OptionalAttr<SymbolRefArrayAttr>:$privatizations,
1176+
Variadic<AnyType>:$reductionOperands,
1177+
OptionalAttr<SymbolRefArrayAttr>:$reductionRecipes,
1178+
Variadic<OpenACC_PointerLikeTypeInterface>:$cacheOperands);
11591179

11601180
let results = (outs Variadic<AnyType>:$results);
11611181

@@ -1181,6 +1201,7 @@ def OpenACC_LoopOp : OpenACC_Op<"loop",
11811201
| `reduction` `(` custom<SymOperandList>(
11821202
$reductionOperands, type($reductionOperands), $reductionRecipes)
11831203
`)`
1204+
| `cache` `(` $cacheOperands `:` type($cacheOperands) `)`
11841205
)
11851206
$region
11861207
( `(` type($results)^ `)` )?

mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,19 @@ LogicalResult acc::UseDeviceOp::verify() {
299299
return success();
300300
}
301301

302+
//===----------------------------------------------------------------------===//
303+
// CacheOp
304+
//===----------------------------------------------------------------------===//
305+
LogicalResult acc::CacheOp::verify() {
306+
// Test for all clauses this operation can be decomposed from:
307+
if (getDataClause() != acc::DataClause::acc_cache &&
308+
getDataClause() != acc::DataClause::acc_cache_readonly)
309+
return emitError(
310+
"data clause associated with cache operation must match its intent"
311+
" or specify original clause this operation was decomposed from");
312+
return success();
313+
}
314+
302315
template <typename StructureOp>
303316
static ParseResult parseRegions(OpAsmParser &parser, OperationState &state,
304317
unsigned nRegions = 1) {

mlir/test/Dialect/OpenACC/ops.mlir

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ func.func @compute3(%a: memref<10x10xf32>, %b: memref<10x10xf32>, %c: memref<10x
213213

214214
// -----
215215

216-
func.func @testloopop() -> () {
216+
func.func @testloopop(%a : memref<10xf32>) -> () {
217217
%i64Value = arith.constant 1 : i64
218218
%i32Value = arith.constant 128 : i32
219219
%idxValue = arith.constant 8 : index
@@ -282,6 +282,11 @@ func.func @testloopop() -> () {
282282
"test.openacc_dummy_op"() : () -> ()
283283
acc.yield
284284
}
285+
%b = acc.cache varPtr(%a : memref<10xf32>) -> memref<10xf32>
286+
acc.loop cache(%b : memref<10xf32>) {
287+
"test.openacc_dummy_op"() : () -> ()
288+
acc.yield
289+
}
285290
return
286291
}
287292

@@ -352,6 +357,11 @@ func.func @testloopop() -> () {
352357
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
353358
// CHECK-NEXT: acc.yield
354359
// CHECK-NEXT: }
360+
// CHECK: %{{.*}} = acc.cache varPtr(%{{.*}} : memref<10xf32>) -> memref<10xf32>
361+
// CHECK-NEXT: acc.loop cache(%{{.*}} : memref<10xf32>) {
362+
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
363+
// CHECK-NEXT: acc.yield
364+
// CHECK-NEXT: }
355365

356366
// -----
357367

0 commit comments

Comments
 (0)