[mlir][openacc] Conversion of data operands in acc.parallel to LLVM IR dialect

Convert data operands from the acc.parallel operation using the same conversion pattern than D102170.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D103337
This commit is contained in:
Valentin Clement 2021-06-07 11:21:51 -04:00 committed by clementval
parent 54f059c900
commit cfcdebaf32
4 changed files with 107 additions and 0 deletions

View File

@ -139,6 +139,12 @@ def OpenACC_ParallelOp : OpenACC_Op<"parallel",
static StringRef getAttachKeyword() { return "attach"; }
static StringRef getPrivateKeyword() { return "private"; }
static StringRef getFirstPrivateKeyword() { return "firstprivate"; }
/// The number of data operands.
unsigned getNumDataOperands();
/// The i-th data operand passed.
Value getDataOperand(unsigned i);
}];
let verifier = ?;

View File

@ -140,6 +140,7 @@ void mlir::populateOpenACCToLLVMConversionPatterns(
patterns.add<LegalizeDataOpForLLVMTranslation<acc::DataOp>>(converter);
patterns.add<LegalizeDataOpForLLVMTranslation<acc::EnterDataOp>>(converter);
patterns.add<LegalizeDataOpForLLVMTranslation<acc::ExitDataOp>>(converter);
patterns.add<LegalizeDataOpForLLVMTranslation<acc::ParallelOp>>(converter);
patterns.add<LegalizeDataOpForLLVMTranslation<acc::UpdateOp>>(converter);
}
@ -201,6 +202,24 @@ void ConvertOpenACCToLLVMPass::runOnOperation() {
allDataOperandsAreConverted(op.detachOperands());
});
target.addDynamicallyLegalOp<acc::ParallelOp>(
[allDataOperandsAreConverted](acc::ParallelOp op) {
return allDataOperandsAreConverted(op.reductionOperands()) &&
allDataOperandsAreConverted(op.copyOperands()) &&
allDataOperandsAreConverted(op.copyinOperands()) &&
allDataOperandsAreConverted(op.copyinReadonlyOperands()) &&
allDataOperandsAreConverted(op.copyoutOperands()) &&
allDataOperandsAreConverted(op.copyoutZeroOperands()) &&
allDataOperandsAreConverted(op.createOperands()) &&
allDataOperandsAreConverted(op.createZeroOperands()) &&
allDataOperandsAreConverted(op.noCreateOperands()) &&
allDataOperandsAreConverted(op.presentOperands()) &&
allDataOperandsAreConverted(op.devicePtrOperands()) &&
allDataOperandsAreConverted(op.attachOperands()) &&
allDataOperandsAreConverted(op.gangPrivateOperands()) &&
allDataOperandsAreConverted(op.gangFirstPrivateOperands());
});
target.addDynamicallyLegalOp<acc::UpdateOp>(
[allDataOperandsAreConverted](acc::UpdateOp op) {
return allDataOperandsAreConverted(op.hostOperands()) &&

View File

@ -448,6 +448,26 @@ static void print(OpAsmPrinter &printer, ParallelOp &op) {
op->getAttrs(), ParallelOp::getOperandSegmentSizeAttr());
}
unsigned ParallelOp::getNumDataOperands() {
return reductionOperands().size() + copyOperands().size() +
copyinOperands().size() + copyinReadonlyOperands().size() +
copyoutOperands().size() + copyoutZeroOperands().size() +
createOperands().size() + createZeroOperands().size() +
noCreateOperands().size() + presentOperands().size() +
devicePtrOperands().size() + attachOperands().size() +
gangPrivateOperands().size() + gangFirstPrivateOperands().size();
}
Value ParallelOp::getDataOperand(unsigned i) {
unsigned numOptional = async() ? 1 : 0;
numOptional += numGangs() ? 1 : 0;
numOptional += numWorkers() ? 1 : 0;
numOptional += vectorLength() ? 1 : 0;
numOptional += ifCond() ? 1 : 0;
numOptional += selfCond() ? 1 : 0;
return getOperand(waitOperands().size() + numOptional + i);
}
//===----------------------------------------------------------------------===//
// LoopOp
//===----------------------------------------------------------------------===//

View File

@ -159,3 +159,65 @@ func @testdataregion(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
}
// CHECK: acc.data present(%{{.*}}, %{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>, !llvm.struct<"openacc_data.1", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>)
// -----
func @testparallelop(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
acc.parallel copy(%b : memref<10xf32>) copyout(%a : memref<10xf32>) {
}
return
}
// CHECK: acc.parallel copy(%{{.*}}: !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>) copyout(%{{.*}}: !llvm.struct<"openacc_data.1", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>)
// -----
func @testparallelop(%a: !llvm.ptr<f32>, %b: memref<10xf32>, %c: !llvm.ptr<f32>) -> () {
acc.parallel copyin(%b : memref<10xf32>) deviceptr(%c: !llvm.ptr<f32>) attach(%a : !llvm.ptr<f32>) {
}
return
}
// CHECK: acc.parallel copyin(%{{.*}}: !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>) deviceptr(%{{.*}}: !llvm.ptr<f32>) attach(%{{.*}}: !llvm.ptr<f32>)
// -----
func @testparallelop(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
%ifCond = constant true
acc.parallel if(%ifCond) copyin_readonly(%b : memref<10xf32>) copyout_zero(%a : memref<10xf32>) {
}
return
}
// CHECK: acc.parallel if(%{{.*}}) copyin_readonly(%{{.*}}: !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>) copyout_zero(%{{.*}}: !llvm.struct<"openacc_data.1", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>)
// -----
func @testparallelop(%a: !llvm.ptr<f32>, %b: memref<10xf32>, %c: !llvm.ptr<f32>) -> () {
acc.parallel create(%b : memref<10xf32>) create_zero(%c: !llvm.ptr<f32>) no_create(%a : !llvm.ptr<f32>) {
}
return
}
// CHECK: acc.parallel create(%{{.*}}: !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>) create_zero(%{{.*}}: !llvm.ptr<f32>) no_create(%{{.*}}: !llvm.ptr<f32>)
// -----
func @testparallelop(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
acc.parallel present(%a: memref<10xf32>, %b: memref<10xf32>) {
}
return
}
// CHECK: acc.parallel present(%{{.*}}: !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>, %{{.*}}: !llvm.struct<"openacc_data.1", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>)
// -----
func @testparallelop(%i: i64, %a: memref<10xf32>, %b: memref<10xf32>) -> () {
acc.parallel num_gangs(%i: i64) present(%a: memref<10xf32>, %b: memref<10xf32>) {
} attributes {async}
return
}
// CHECK: acc.parallel num_gangs(%{{.*}}: i64) present(%{{.*}}: !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>, %{{.*}}: !llvm.struct<"openacc_data.1", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>)
// CHECK-NEXT: } attributes {async}