diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td --- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td @@ -175,8 +175,11 @@ let arguments = (ins Variadic:$presentOperands, Variadic:$copyOperands, Variadic:$copyinOperands, + Variadic:$copyinReadonlyOperands, Variadic:$copyoutOperands, + Variadic:$copyoutZeroOperands, Variadic:$createOperands, + Variadic:$createZeroOperands, Variadic:$noCreateOperands, Variadic:$deleteOperands, Variadic:$attachOperands, @@ -189,9 +192,12 @@ static StringRef getDeleteKeyword() { return "delete"; } static StringRef getDetachKeyword() { return "detach"; } static StringRef getCopyinKeyword() { return "copyin"; } + static StringRef getCopyinReadonlyKeyword() { return "copyin_readonly"; } static StringRef getCopyKeyword() { return "copy"; } static StringRef getCopyoutKeyword() { return "copyout"; } + static StringRef getCopyoutZeroKeyword() { return "copyout_zero"; } static StringRef getCreateKeyword() { return "create"; } + static StringRef getCreateZeroKeyword() { return "create_zero"; } static StringRef getNoCreateKeyword() { return "no_create"; } static StringRef getPresentKeyword() { return "present"; } }]; diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp --- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp +++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp @@ -420,8 +420,11 @@ /// operation := `acc.parallel` `present` `(` value-list `)`? /// `copy` `(` value-list `)`? /// `copyin` `(` value-list `)`? +/// `copyin_readonly` `(` value-list `)`? /// `copyout` `(` value-list `)`? +/// `copyout_zero` `(` value-list `)`? /// `create` `(` value-list `)`? +/// `create_zero` `(` value-list `)`? /// `no_create` `(` value-list `)`? /// `delete` `(` value-list `)`? /// `attach` `(` value-list `)`? @@ -430,70 +433,96 @@ static ParseResult parseDataOp(OpAsmParser &parser, OperationState &result) { Builder &builder = parser.getBuilder(); SmallVector presentOperands, copyOperands, - copyinOperands, copyoutOperands, createOperands, noCreateOperands, + copyinOperands, copyinReadonlyOperands, copyoutOperands, + copyoutZeroOperands, createOperands, createZeroOperands, noCreateOperands, deleteOperands, attachOperands, detachOperands; - SmallVector operandsTypes; + SmallVector presentOperandTypes, copyOperandTypes, + copyinOperandTypes, copyinReadonlyOperandTypes, copyoutOperandTypes, + copyoutZeroOperandTypes, createOperandTypes, createZeroOperandTypes, + noCreateOperandTypes, deleteOperandTypes, attachOperandTypes, + detachOperandTypes; // present(value-list)? if (failed(parseOperandList(parser, DataOp::getPresentKeyword(), - presentOperands, operandsTypes, result))) + presentOperands, presentOperandTypes, result))) return failure(); // copy(value-list)? if (failed(parseOperandList(parser, DataOp::getCopyKeyword(), copyOperands, - operandsTypes, result))) + copyOperandTypes, result))) return failure(); // copyin(value-list)? if (failed(parseOperandList(parser, DataOp::getCopyinKeyword(), - copyinOperands, operandsTypes, result))) + copyinOperands, copyinOperandTypes, result))) + return failure(); + + // copyin_readonly(value-list)? + if (failed(parseOperandList(parser, DataOp::getCopyinReadonlyKeyword(), + copyinReadonlyOperands, copyinOperandTypes, + result))) return failure(); // copyout(value-list)? if (failed(parseOperandList(parser, DataOp::getCopyoutKeyword(), - copyoutOperands, operandsTypes, result))) + copyoutOperands, copyoutOperandTypes, result))) + return failure(); + + // copyout_zero(value-list)? + if (failed(parseOperandList(parser, DataOp::getCopyoutZeroKeyword(), + copyoutZeroOperands, copyoutZeroOperandTypes, + result))) return failure(); // create(value-list)? if (failed(parseOperandList(parser, DataOp::getCreateKeyword(), - createOperands, operandsTypes, result))) + createOperands, createOperandTypes, result))) + return failure(); + + // create_zero(value-list)? + if (failed(parseOperandList(parser, DataOp::getCreateZeroKeyword(), + createZeroOperands, createZeroOperandTypes, + result))) return failure(); // no_create(value-list)? - if (failed(parseOperandList(parser, DataOp::getCreateKeyword(), - noCreateOperands, operandsTypes, result))) + if (failed(parseOperandList(parser, DataOp::getNoCreateKeyword(), + noCreateOperands, noCreateOperandTypes, result))) return failure(); // delete(value-list)? if (failed(parseOperandList(parser, DataOp::getDeleteKeyword(), - deleteOperands, operandsTypes, result))) + deleteOperands, deleteOperandTypes, result))) return failure(); // attach(value-list)? if (failed(parseOperandList(parser, DataOp::getAttachKeyword(), - attachOperands, operandsTypes, result))) + attachOperands, attachOperandTypes, result))) return failure(); // detach(value-list)? if (failed(parseOperandList(parser, DataOp::getDetachKeyword(), - detachOperands, operandsTypes, result))) + detachOperands, detachOperandTypes, result))) return failure(); // Data op region if (failed(parseRegions(parser, result))) return failure(); - result.addAttribute( - ParallelOp::getOperandSegmentSizeAttr(), - builder.getI32VectorAttr({static_cast(presentOperands.size()), - static_cast(copyOperands.size()), - static_cast(copyinOperands.size()), - static_cast(copyoutOperands.size()), - static_cast(createOperands.size()), - static_cast(noCreateOperands.size()), - static_cast(deleteOperands.size()), - static_cast(attachOperands.size()), - static_cast(detachOperands.size())})); + result.addAttribute(ParallelOp::getOperandSegmentSizeAttr(), + builder.getI32VectorAttr( + {static_cast(presentOperands.size()), + static_cast(copyOperands.size()), + static_cast(copyinOperands.size()), + static_cast(copyinReadonlyOperands.size()), + static_cast(copyoutOperands.size()), + static_cast(copyoutZeroOperands.size()), + static_cast(createOperands.size()), + static_cast(createZeroOperands.size()), + static_cast(noCreateOperands.size()), + static_cast(deleteOperands.size()), + static_cast(attachOperands.size()), + static_cast(detachOperands.size())})); // Additional attributes if (failed(parser.parseOptionalAttrDictWithKeyword(result.attributes))) @@ -514,12 +543,24 @@ // copyin(value-list)? printOperandList(op.copyinOperands(), DataOp::getCopyinKeyword(), printer); + // copyin_readonly(value-list)? + printOperandList(op.copyinReadonlyOperands(), + DataOp::getCopyinReadonlyKeyword(), printer); + // copyout(value-list)? printOperandList(op.copyoutOperands(), DataOp::getCopyoutKeyword(), printer); + // copyout(value-list)? + printOperandList(op.copyoutZeroOperands(), DataOp::getCopyoutZeroKeyword(), + printer); + // create(value-list)? printOperandList(op.createOperands(), DataOp::getCreateKeyword(), printer); + // create_zero(value-list)? + printOperandList(op.createZeroOperands(), DataOp::getCreateZeroKeyword(), + printer); + // no_create(value-list)? printOperandList(op.noCreateOperands(), DataOp::getNoCreateKeyword(), printer); diff --git a/mlir/test/Dialect/OpenACC/ops.mlir b/mlir/test/Dialect/OpenACC/ops.mlir --- a/mlir/test/Dialect/OpenACC/ops.mlir +++ b/mlir/test/Dialect/OpenACC/ops.mlir @@ -1,8 +1,8 @@ -// RUN: mlir-opt -allow-unregistered-dialect %s | FileCheck %s +// RUN: mlir-opt -split-input-file -allow-unregistered-dialect %s | FileCheck %s // Verify the printed output can be parsed. -// RUN: mlir-opt -allow-unregistered-dialect %s | mlir-opt -allow-unregistered-dialect | FileCheck %s +// RUN: mlir-opt -split-input-file -allow-unregistered-dialect %s | mlir-opt -allow-unregistered-dialect | FileCheck %s // Verify the generic form can be parsed. -// RUN: mlir-opt -allow-unregistered-dialect -mlir-print-op-generic %s | mlir-opt -allow-unregistered-dialect | FileCheck %s +// RUN: mlir-opt -split-input-file -allow-unregistered-dialect -mlir-print-op-generic %s | mlir-opt -allow-unregistered-dialect | FileCheck %s func @compute1(%A: memref<10x10xf32>, %B: memref<10x10xf32>, %C: memref<10x10xf32>) -> memref<10x10xf32> { %c0 = constant 0 : index @@ -58,6 +58,8 @@ // CHECK-NEXT: return %{{.*}} : memref<10x10xf32> // CHECK-NEXT: } +// ----- + func @compute2(%A: memref<10x10xf32>, %B: memref<10x10xf32>, %C: memref<10x10xf32>) -> memref<10x10xf32> { %c0 = constant 0 : index %c10 = constant 10 : index @@ -110,6 +112,7 @@ // CHECK-NEXT: return %{{.*}} : memref<10x10xf32> // CHECK-NEXT: } +// ----- func @compute3(%a: memref<10x10xf32>, %b: memref<10x10xf32>, %c: memref<10xf32>, %d: memref<10xf32>) -> memref<10xf32> { %lb = constant 0 : index @@ -192,6 +195,8 @@ // CHECK-NEXT: return %{{.*}} : memref<10xf32> // CHECK-NEXT: } +// ----- + func @testop(%a: memref<10xf32>) -> () { %workerNum = constant 1 : i64 %vectorLength = constant 128 : i64 @@ -271,6 +276,7 @@ // CHECK-NEXT: acc.yield // CHECK-NEXT: } +// ----- func @testparallelop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () { %i64value = constant 1 : i64 @@ -387,3 +393,63 @@ // CHECK-NEXT: } attributes {defaultAttr = "none"} // CHECK: acc.parallel { // CHECK-NEXT: } attributes {defaultAttr = "present"} + +// ----- + +func @testdataop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () { + acc.data present(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) { + } + acc.data copy(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) { + } + acc.data copyin(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) { + } + acc.data copyin_readonly(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) { + } + acc.data copyout(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) { + } + acc.data copyout_zero(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) { + } + acc.data create(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) { + } + acc.data create_zero(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) { + } + acc.data no_create(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) { + } + acc.data delete(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) { + } + acc.data attach(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) { + } + acc.data detach(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) { + } + acc.data present(%a: memref<10xf32>) copyin(%b: memref<10xf32>) copyout(%c: memref<10x10xf32>) { + } + return +} + +// CHECK: func @testdataop([[ARGA:%.*]]: memref<10xf32>, [[ARGB:%.*]]: memref<10xf32>, [[ARGC:%.*]]: memref<10x10xf32>) { +// CHECK: acc.data present([[ARGA]]: memref<10xf32>, [[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) { +// CHECK-NEXT: } +// CHECK: acc.data copy([[ARGA]]: memref<10xf32>, [[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) { +// CHECK-NEXT: } +// CHECK: acc.data copyin([[ARGA]]: memref<10xf32>, [[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) { +// CHECK-NEXT: } +// CHECK: acc.data copyin_readonly([[ARGA]]: memref<10xf32>, [[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) { +// CHECK-NEXT: } +// CHECK: acc.data copyout([[ARGA]]: memref<10xf32>, [[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) { +// CHECK-NEXT: } +// CHECK: acc.data copyout_zero([[ARGA]]: memref<10xf32>, [[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) { +// CHECK-NEXT: } +// CHECK: acc.data create([[ARGA]]: memref<10xf32>, [[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) { +// CHECK-NEXT: } +// CHECK: acc.data create_zero([[ARGA]]: memref<10xf32>, [[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) { +// CHECK-NEXT: } +// CHECK: acc.data no_create([[ARGA]]: memref<10xf32>, [[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) { +// CHECK-NEXT: } +// CHECK: acc.data delete([[ARGA]]: memref<10xf32>, [[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) { +// CHECK-NEXT: } +// CHECK: acc.data attach([[ARGA]]: memref<10xf32>, [[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) { +// CHECK-NEXT: } +// CHECK: acc.data detach([[ARGA]]: memref<10xf32>, [[ARGB]]: memref<10xf32>, [[ARGC]]: memref<10x10xf32>) { +// CHECK-NEXT: } +// CHECK: acc.data present([[ARGA]]: memref<10xf32>) copyin([[ARGB]]: memref<10xf32>) copyout([[ARGC]]: memref<10x10xf32>) { +// CHECK-NEXT: }