[Mlir-commits] [mlir] ecc9978 - [mlir][openacc] Add update operation
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Sep 29 06:58:04 PDT 2020
Author: Valentin Clement
Date: 2020-09-29T09:57:57-04:00
New Revision: ecc997807180a6e763f12e3d011f6b887db0d6a9
URL: https://github.com/llvm/llvm-project/commit/ecc997807180a6e763f12e3d011f6b887db0d6a9
DIFF: https://github.com/llvm/llvm-project/commit/ecc997807180a6e763f12e3d011f6b887db0d6a9.diff
LOG: [mlir][openacc] Add update operation
This patch introduce the update operation that represent the OpenACC update directive.
Reviewed By: ftynse
Differential Revision: https://reviews.llvm.org/D88102
Added:
Modified:
mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
mlir/test/Dialect/OpenACC/invalid.mlir
mlir/test/Dialect/OpenACC/ops.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
index 85499834e5a2..862a35718f06 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
@@ -318,4 +318,44 @@ def OpenACC_YieldOp : OpenACC_Op<"yield", [Terminator,
let assemblyFormat = "attr-dict ($operands^ `:` type($operands))?";
}
+//===----------------------------------------------------------------------===//
+// 2.14.4. Update Directive
+//===----------------------------------------------------------------------===//
+
+def OpenACC_UpdateOp : OpenACC_Op<"update", [AttrSizedOperandSegments]> {
+ let summary = "update operation";
+
+ let description = [{
+ The "acc.udpate" operation represents the OpenACC update executable
+ directive.
+ As host and self clauses are synonyms, any operands for host and self are
+ add to $hostOperands.
+
+ Example:
+
+ ```mlir
+ acc.update device(%d1 : memref<10xf32>) attributes {async}
+ ```
+ }];
+
+ let arguments = (ins Optional<IntOrIndex>:$asyncOperand,
+ Optional<IntOrIndex>:$waitDevnum,
+ Variadic<IntOrIndex>:$waitOperands,
+ UnitAttr:$async,
+ UnitAttr:$wait,
+ Variadic<AnyType>:$hostOperands,
+ Variadic<AnyType>:$deviceOperands,
+ UnitAttr:$ifPresent);
+
+ let assemblyFormat = [{
+ ( `async` `(` $asyncOperand^ `:` type($asyncOperand) `)` )?
+ ( `wait_devnum` `(` $waitDevnum^ `:` type($waitDevnum) `)` )?
+ ( `wait` `(` $waitOperands^ `:` type($waitOperands) `)` )?
+ ( `host` `(` $hostOperands^ `:` type($hostOperands) `)` )?
+ ( `device` `(` $deviceOperands^ `:` type($deviceOperands) `)` )?
+ attr-dict-with-keyword
+ }];
+}
+
+
#endif // OPENACC_OPS
diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index ca2acca974e8..46df60532e1a 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -645,6 +645,33 @@ static LogicalResult verify(acc::DataOp dataOp) {
if (dataOp.getOperands().size() == 0 && !dataOp.defaultAttr())
return dataOp.emitError("at least one operand or the default attribute "
"must appear on the data operation");
+ return success();
+}
+
+//===----------------------------------------------------------------------===//
+// UpdateOp
+//===----------------------------------------------------------------------===//
+
+static LogicalResult verify(acc::UpdateOp updateOp) {
+ // At least one of host or device should have a value.
+ if (updateOp.hostOperands().size() == 0 &&
+ updateOp.deviceOperands().size() == 0)
+ return updateOp.emitError("at least one value must be present in"
+ " hostOperands or deviceOperands");
+
+ // The async attribute represent the async clause without value. Therefore the
+ // attribute and operand cannot appear at the same time.
+ if (updateOp.asyncOperand() && updateOp.async())
+ return updateOp.emitError("async attribute cannot appear with "
+ " asyncOperand");
+
+ // The wait attribute represent the wait clause without values. Therefore the
+ // attribute and operands cannot appear at the same time.
+ if (updateOp.waitOperands().size() > 0 && updateOp.wait())
+ return updateOp.emitError("wait attribute cannot appear with waitOperands");
+
+ if (updateOp.waitDevnum() && updateOp.waitOperands().size() == 0)
+ return updateOp.emitError("wait_devnum cannot appear without waitOperands");
return success();
}
diff --git a/mlir/test/Dialect/OpenACC/invalid.mlir b/mlir/test/Dialect/OpenACC/invalid.mlir
index 22345d279f0d..c694fc5361cf 100644
--- a/mlir/test/Dialect/OpenACC/invalid.mlir
+++ b/mlir/test/Dialect/OpenACC/invalid.mlir
@@ -75,3 +75,26 @@ acc.data {
}
// -----
+// expected-error at +1 {{at least one value must be present in hostOperands or deviceOperands}}
+acc.update
+
+// -----
+
+%cst = constant 1 : index
+%value = alloc() : memref<10xf32>
+// expected-error at +1 {{wait_devnum cannot appear without waitOperands}}
+acc.update wait_devnum(%cst: index) host(%value: memref<10xf32>)
+
+// -----
+
+%cst = constant 1 : index
+%value = alloc() : memref<10xf32>
+// expected-error at +1 {{async attribute cannot appear with asyncOperand}}
+acc.update async(%cst: index) host(%value: memref<10xf32>) attributes {async}
+
+// -----
+
+%cst = constant 1 : index
+%value = alloc() : memref<10xf32>
+// expected-error at +1 {{wait attribute cannot appear with waitOperands}}
+acc.update wait(%cst: index) host(%value: memref<10xf32>) attributes {wait}
diff --git a/mlir/test/Dialect/OpenACC/ops.mlir b/mlir/test/Dialect/OpenACC/ops.mlir
index a4fecf619a77..c383d067f285 100644
--- a/mlir/test/Dialect/OpenACC/ops.mlir
+++ b/mlir/test/Dialect/OpenACC/ops.mlir
@@ -524,3 +524,33 @@ func @testdataop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>)
// CHECK-NEXT: } attributes {defaultAttr = "present"}
// CHECK: acc.data {
// CHECK-NEXT: } attributes {defaultAttr = "none"}
+
+// -----
+
+func @testupdateop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () {
+ %i64Value = constant 1 : i64
+ %i32Value = constant 1 : i32
+ %idxValue = constant 1 : index
+ acc.update async(%i64Value: i64) host(%a: memref<10xf32>)
+ acc.update async(%i32Value: i32) host(%a: memref<10xf32>)
+ acc.update async(%idxValue: index) host(%a: memref<10xf32>)
+ acc.update wait_devnum(%i64Value: i64) wait(%i32Value, %idxValue : i32, index) host(%a: memref<10xf32>)
+ acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>)
+ acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>) attributes {async}
+ acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>) attributes {wait}
+ acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>) attributes {ifPresent}
+ return
+}
+
+// CHECK: func @testupdateop([[ARGA:%.*]]: memref<10xf32>, [[ARGB:%.*]]: memref<10xf32>, [[ARGC:%.*]]: memref<10x10xf32>) {
+// CHECK: [[I64VALUE:%.*]] = constant 1 : i64
+// CHECK: [[I32VALUE:%.*]] = constant 1 : i32
+// CHECK: [[IDXVALUE:%.*]] = constant 1 : index
+// CHECK: acc.update async([[I64VALUE]] : i64) host([[ARGA]] : memref<10xf32>)
+// CHECK: acc.update async([[I32VALUE]] : i32) host([[ARGA]] : memref<10xf32>)
+// CHECK: acc.update async([[IDXVALUE]] : index) host([[ARGA]] : memref<10xf32>)
+// CHECK: acc.update wait_devnum([[I64VALUE]] : i64) wait([[I32VALUE]], [[IDXVALUE]] : i32, index) host([[ARGA]] : memref<10xf32>)
+// CHECK: acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>)
+// CHECK: acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) attributes {async}
+// CHECK: acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) attributes {wait}
+// CHECK: acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) attributes {ifPresent}
More information about the Mlir-commits
mailing list