[Mlir-commits] [mlir] 01f5fcd - [mlir][openacc] Add loop op verifier
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Sep 15 08:42:15 PDT 2020
Author: Valentin Clement
Date: 2020-09-15T11:42:08-04:00
New Revision: 01f5fcd8290349265e6039ad9089b086ea783f00
URL: https://github.com/llvm/llvm-project/commit/01f5fcd8290349265e6039ad9089b086ea783f00
DIFF: https://github.com/llvm/llvm-project/commit/01f5fcd8290349265e6039ad9089b086ea783f00.diff
LOG: [mlir][openacc] Add loop op verifier
Add a verifier for the loop op in the OpenACC dialect. Check basic restriction
from 2.9 Loop construct from the OpenACC 3.0 specs.
Reviewed By: ftynse
Differential Revision: https://reviews.llvm.org/D87546
Added:
mlir/test/Dialect/OpenACC/invalid.mlir
Modified:
mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
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 c0178ebe9e48..0d37215ea4e5 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
@@ -200,7 +200,8 @@ def OpenACC_TerminatorOp : OpenACC_Op<"terminator", [Terminator]> {
//===----------------------------------------------------------------------===//
def OpenACC_LoopOp : OpenACC_Op<"loop",
- [AttrSizedOperandSegments]> {
+ [AttrSizedOperandSegments,
+ SingleBlockImplicitTerminator<"acc::YieldOp">]> {
let summary = "loop construct";
let description = [{
@@ -228,13 +229,14 @@ def OpenACC_LoopOp : OpenACC_Op<"loop",
Optional<AnyInteger>:$gangStatic,
Optional<AnyInteger>:$workerNum,
Optional<AnyInteger>:$vectorLength,
- UnitAttr:$loopSeq,
- UnitAttr:$loopIndependent,
- UnitAttr:$loopAuto,
+ UnitAttr:$seq,
+ UnitAttr:$independent,
+ UnitAttr:$auto_,
Variadic<AnyInteger>:$tileOperands,
Variadic<AnyType>:$privateOperands,
OptionalAttr<OpenACC_ReductionOpAttr>:$reductionOp,
- Variadic<AnyType>:$reductionOperands);
+ Variadic<AnyType>:$reductionOperands,
+ DefaultValuedAttr<I64Attr, "0">:$exec_mapping);
let results = (outs Variadic<AnyType>:$results);
@@ -256,7 +258,7 @@ def OpenACC_LoopOp : OpenACC_Op<"loop",
static StringRef getReductionKeyword() { return "reduction"; }
}];
- let verifier = ?;
+ let verifier = [{ return ::verifyLoopOp(*this); }];
}
// Yield operation for the acc.loop and acc.parallel operations.
diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index 11a774828194..3e4d1c3f0e7d 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -487,7 +487,7 @@ static void print(OpAsmPrinter &printer, DataOp &op) {
/// region attr-dict?
static ParseResult parseLoopOp(OpAsmParser &parser, OperationState &result) {
Builder &builder = parser.getBuilder();
- unsigned executionMapping = 0;
+ unsigned executionMapping = OpenACCExecMapping::NONE;
SmallVector<Type, 8> operandTypes;
SmallVector<OpAsmParser::OperandType, 8> privateOperands, reductionOperands;
SmallVector<OpAsmParser::OperandType, 8> tileOperands;
@@ -567,7 +567,7 @@ static ParseResult parseLoopOp(OpAsmParser &parser, OperationState &result) {
reductionOperands, operandTypes, result)))
return failure();
- if (executionMapping != 0)
+ if (executionMapping != acc::OpenACCExecMapping::NONE)
result.addAttribute(LoopOp::getExecutionMappingAttrName(),
builder.getI64IntegerAttr(executionMapping));
@@ -597,13 +597,7 @@ static ParseResult parseLoopOp(OpAsmParser &parser, OperationState &result) {
static void print(OpAsmPrinter &printer, LoopOp &op) {
printer << LoopOp::getOperationName();
- unsigned execMapping =
- (op.getAttrOfType<IntegerAttr>(LoopOp::getExecutionMappingAttrName()) !=
- nullptr)
- ? op.getAttrOfType<IntegerAttr>(LoopOp::getExecutionMappingAttrName())
- .getInt()
- : 0;
-
+ unsigned execMapping = op.exec_mapping();
if (execMapping & OpenACCExecMapping::GANG) {
printer << " " << LoopOp::getGangKeyword();
Value gangNum = op.gangNum();
@@ -661,5 +655,31 @@ static void print(OpAsmPrinter &printer, LoopOp &op) {
LoopOp::getOperandSegmentSizeAttr()});
}
+static LogicalResult verifyLoopOp(acc::LoopOp loopOp) {
+ // auto, independent and seq attribute are mutually exclusive.
+ if ((loopOp.auto_() && (loopOp.independent() || loopOp.seq())) ||
+ (loopOp.independent() && loopOp.seq())) {
+ loopOp.emitError("only one of " + acc::LoopOp::getAutoAttrName() + ", " +
+ acc::LoopOp::getIndependentAttrName() + ", " +
+ acc::LoopOp::getSeqAttrName() +
+ " can be present at the same time");
+ return failure();
+ }
+
+ // Gang, worker and vector are incompatible with seq.
+ if (loopOp.seq() && loopOp.exec_mapping() != OpenACCExecMapping::NONE) {
+ loopOp.emitError("gang, worker or vector cannot appear with the seq attr");
+ return failure();
+ }
+
+ // Check non-empty body().
+ if (loopOp.region().empty()) {
+ loopOp.emitError("expected non-empty body.");
+ return failure();
+ }
+
+ return success();
+}
+
#define GET_OP_CLASSES
#include "mlir/Dialect/OpenACC/OpenACCOps.cpp.inc"
diff --git a/mlir/test/Dialect/OpenACC/invalid.mlir b/mlir/test/Dialect/OpenACC/invalid.mlir
new file mode 100644
index 000000000000..61a13211ba26
--- /dev/null
+++ b/mlir/test/Dialect/OpenACC/invalid.mlir
@@ -0,0 +1,70 @@
+// RUN: mlir-opt -split-input-file -verify-diagnostics %s
+
+// expected-error at +1 {{gang, worker or vector cannot appear with the seq attr}}
+acc.loop gang {
+ "some.op"() : () -> ()
+ acc.yield
+} attributes {seq}
+
+// -----
+
+// expected-error at +1 {{gang, worker or vector cannot appear with the seq attr}}
+acc.loop worker {
+ "some.op"() : () -> ()
+ acc.yield
+} attributes {seq}
+
+// -----
+
+// expected-error at +1 {{gang, worker or vector cannot appear with the seq attr}}
+acc.loop vector {
+ "some.op"() : () -> ()
+ acc.yield
+} attributes {seq}
+
+// -----
+
+// expected-error at +1 {{gang, worker or vector cannot appear with the seq attr}}
+acc.loop gang worker {
+ "some.op"() : () -> ()
+ acc.yield
+} attributes {seq}
+
+// -----
+
+// expected-error at +1 {{gang, worker or vector cannot appear with the seq attr}}
+acc.loop gang vector {
+ "some.op"() : () -> ()
+ acc.yield
+} attributes {seq}
+
+// -----
+
+// expected-error at +1 {{gang, worker or vector cannot appear with the seq attr}}
+acc.loop worker vector {
+ "some.op"() : () -> ()
+ acc.yield
+} attributes {seq}
+
+// -----
+
+// expected-error at +1 {{gang, worker or vector cannot appear with the seq attr}}
+acc.loop gang worker vector {
+ "some.op"() : () -> ()
+ acc.yield
+} attributes {seq}
+
+// -----
+
+// expected-error at +1 {{expected non-empty body.}}
+acc.loop {
+}
+
+// -----
+
+// expected-error at +1 {{only one of auto, independent, seq can be present at the same time}}
+acc.loop {
+ acc.yield
+} attributes {auto_, seq}
+
+// -----
diff --git a/mlir/test/Dialect/OpenACC/ops.mlir b/mlir/test/Dialect/OpenACC/ops.mlir
index b534f703e05e..b1a78c61d65d 100644
--- a/mlir/test/Dialect/OpenACC/ops.mlir
+++ b/mlir/test/Dialect/OpenACC/ops.mlir
@@ -1,8 +1,8 @@
-// RUN: mlir-opt %s | FileCheck %s
+// RUN: mlir-opt -allow-unregistered-dialect %s | FileCheck %s
// Verify the printed output can be parsed.
-// RUN: mlir-opt %s | mlir-opt | FileCheck %s
+// RUN: mlir-opt -allow-unregistered-dialect %s | mlir-opt -allow-unregistered-dialect | FileCheck %s
// Verify the generic form can be parsed.
-// RUN: mlir-opt -mlir-print-op-generic %s | mlir-opt | FileCheck %s
+// RUN: mlir-opt -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
@@ -186,27 +186,43 @@ func @compute3(%a: memref<10x10xf32>, %b: memref<10x10xf32>, %c: memref<10xf32>,
// CHECK-NEXT: return %{{.*}} : memref<10xf32>
// CHECK-NEXT: }
-func @testop() -> () {
+func @testop(%a: memref<10xf32>) -> () {
%workerNum = constant 1 : i64
%vectorLength = constant 128 : i64
%gangNum = constant 8 : i64
%gangStatic = constant 2 : i64
%tileSize = constant 2 : i64
acc.loop gang worker vector {
+ "some.op"() : () -> ()
+ acc.yield
}
acc.loop gang(num: %gangNum) {
+ "some.op"() : () -> ()
+ acc.yield
}
acc.loop gang(static: %gangStatic) {
+ "some.op"() : () -> ()
+ acc.yield
}
acc.loop worker(%workerNum) {
+ "some.op"() : () -> ()
+ acc.yield
}
acc.loop vector(%vectorLength) {
+ "some.op"() : () -> ()
+ acc.yield
}
acc.loop gang(num: %gangNum) worker vector {
+ "some.op"() : () -> ()
+ acc.yield
}
acc.loop gang(num: %gangNum, static: %gangStatic) worker(%workerNum) vector(%vectorLength) {
+ "some.op"() : () -> ()
+ acc.yield
}
acc.loop tile(%tileSize : i64, %tileSize : i64) {
+ "some.op"() : () -> ()
+ acc.yield
}
return
}
@@ -217,20 +233,36 @@ func @testop() -> () {
// CHECK-NEXT: [[GANGSTATIC:%.*]] = constant 2 : i64
// CHECK-NEXT: [[TILESIZE:%.*]] = constant 2 : i64
// CHECK-NEXT: acc.loop gang worker vector {
+// CHECK-NEXT: "some.op"() : () -> ()
+// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
// CHECK-NEXT: acc.loop gang(num: [[GANGNUM]]) {
+// CHECK-NEXT: "some.op"() : () -> ()
+// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
// CHECK-NEXT: acc.loop gang(static: [[GANGSTATIC]]) {
+// CHECK-NEXT: "some.op"() : () -> ()
+// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
// CHECK-NEXT: acc.loop worker([[WORKERNUM]]) {
+// CHECK-NEXT: "some.op"() : () -> ()
+// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
// CHECK-NEXT: acc.loop vector([[VECTORLENGTH]]) {
+// CHECK-NEXT: "some.op"() : () -> ()
+// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
// CHECK-NEXT: acc.loop gang(num: [[GANGNUM]]) worker vector {
+// CHECK-NEXT: "some.op"() : () -> ()
+// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
// CHECK-NEXT: acc.loop gang(num: [[GANGNUM]], static: [[GANGSTATIC]]) worker([[WORKERNUM]]) vector([[VECTORLENGTH]]) {
+// CHECK-NEXT: "some.op"() : () -> ()
+// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
// CHECK-NEXT: acc.loop tile([[TILESIZE]]: i64, [[TILESIZE]]: i64) {
+// CHECK-NEXT: "some.op"() : () -> ()
+// CHECK-NEXT: acc.yield
// CHECK-NEXT: }
More information about the Mlir-commits
mailing list