[Mlir-commits] [mlir] b5c3f17 - [MLIR] Add support for empty IVs to affine.parallel

Frank Laub llvmlistbot at llvm.org
Wed May 26 16:45:25 PDT 2021


Author: Frank Laub
Date: 2021-05-26T23:45:11Z
New Revision: b5c3f17e70e70692e805c00d906a3a3d6678f093

URL: https://github.com/llvm/llvm-project/commit/b5c3f17e70e70692e805c00d906a3a3d6678f093
DIFF: https://github.com/llvm/llvm-project/commit/b5c3f17e70e70692e805c00d906a3a3d6678f093.diff

LOG: [MLIR] Add support for empty IVs to affine.parallel

Allow support for specifying empty IVs in an `affine.parallel`.

For example:

```
affine.parallel () = () to () {
  affine.yield
}
```

Reviewed By: bondhugula, jbruestle

Differential Revision: https://reviews.llvm.org/D102895

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
    mlir/lib/Dialect/Affine/IR/AffineOps.cpp
    mlir/test/Dialect/Affine/ops.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
index 0bd83d6cabc5..dda8d42674cb 100644
--- a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
+++ b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
@@ -601,14 +601,14 @@ def AffineParallelOp : Affine_Op<"parallel",
   let summary = "multi-index parallel band operation";
   let description = [{
     The "affine.parallel" operation represents a hyper-rectangular affine
-    parallel band, defining multiple SSA values for its induction variables. It
-    has one region capturing the parallel band body. The induction variables are
-    represented as arguments of this region. These SSA values always have type
-    index, which is the size of the machine word. The strides, represented by
-    steps, are positive constant integers which defaults to "1" if not present.
-    The lower and upper bounds specify a half-open range: the range includes the
-    lower bound but does not include the upper bound. The body region must
-    contain exactly one block that terminates with "affine.yield".
+    parallel band, defining zero or more SSA values for its induction variables.
+    It has one region capturing the parallel band body. The induction variables
+    are represented as arguments of this region. These SSA values always have
+    type index, which is the size of the machine word. The strides, represented
+    by steps, are positive constant integers which defaults to "1" if not
+    present. The lower and upper bounds specify a half-open range: the range
+    includes the lower bound but does not include the upper bound. The body
+    region must contain exactly one block that terminates with "affine.yield".
 
     The lower and upper bounds of a parallel operation are represented as an
     application of an affine mapping to a list of SSA values passed to the map.

diff  --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
index b267223b423e..7e39fc364913 100644
--- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
+++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
@@ -2641,8 +2641,6 @@ void AffineParallelOp::build(OpBuilder &builder, OperationState &result,
                              ArrayRef<AffineMap> lbMaps, ValueRange lbArgs,
                              ArrayRef<AffineMap> ubMaps, ValueRange ubArgs,
                              ArrayRef<int64_t> steps) {
-  assert(!lbMaps.empty() && "expected the lower bound map to be non-empty");
-  assert(!ubMaps.empty() && "expected the upper bound map to be non-empty");
   assert(llvm::all_of(lbMaps,
                       [lbMaps](AffineMap m) {
                         return m.getNumDims() == lbMaps[0].getNumDims() &&
@@ -2657,12 +2655,14 @@ void AffineParallelOp::build(OpBuilder &builder, OperationState &result,
                       }) &&
          "expected all upper bounds maps to have the same number of dimensions "
          "and symbols");
-  assert(lbMaps[0].getNumInputs() == lbArgs.size() &&
-         "expected lower bound maps to have as many inputs as lower bound "
-         "operands");
-  assert(ubMaps[0].getNumInputs() == ubArgs.size() &&
-         "expected upper bound maps to have as many inputs as upper bound "
-         "operands");
+  assert(lbMaps.empty() ||
+         lbMaps[0].getNumInputs() == lbArgs.size() &&
+             "expected lower bound maps to have as many inputs as lower bound "
+             "operands");
+  assert(ubMaps.empty() ||
+         ubMaps[0].getNumInputs() == ubArgs.size() &&
+             "expected upper bound maps to have as many inputs as upper bound "
+             "operands");
 
   result.addTypes(resultTypes);
 
@@ -2676,8 +2676,10 @@ void AffineParallelOp::build(OpBuilder &builder, OperationState &result,
 
   // Concatenates maps defined in the same input space (same dimensions and
   // symbols), assumes there is at least one map.
-  auto concatMapsSameInput = [](ArrayRef<AffineMap> maps,
-                                SmallVectorImpl<int32_t> &groups) {
+  auto concatMapsSameInput = [&builder](ArrayRef<AffineMap> maps,
+                                        SmallVectorImpl<int32_t> &groups) {
+    if (maps.empty())
+      return AffineMap::get(builder.getContext());
     SmallVector<AffineExpr> exprs;
     groups.reserve(groups.size() + maps.size());
     exprs.reserve(maps.size());
@@ -2685,7 +2687,6 @@ void AffineParallelOp::build(OpBuilder &builder, OperationState &result,
       llvm::append_range(exprs, m.getResults());
       groups.push_back(m.getNumResults());
     }
-    assert(!maps.empty() && "expected a non-empty list of maps");
     return AffineMap::get(maps[0].getNumDims(), maps[0].getNumSymbols(), exprs,
                           maps[0].getContext());
   };
@@ -2696,10 +2697,10 @@ void AffineParallelOp::build(OpBuilder &builder, OperationState &result,
   AffineMap ubMap = concatMapsSameInput(ubMaps, ubGroups);
   result.addAttribute(getLowerBoundsMapAttrName(), AffineMapAttr::get(lbMap));
   result.addAttribute(getLowerBoundsGroupsAttrName(),
-                      builder.getI32VectorAttr(lbGroups));
+                      builder.getI32TensorAttr(lbGroups));
   result.addAttribute(getUpperBoundsMapAttrName(), AffineMapAttr::get(ubMap));
   result.addAttribute(getUpperBoundsGroupsAttrName(),
-                      builder.getI32VectorAttr(ubGroups));
+                      builder.getI32TensorAttr(ubGroups));
   result.addAttribute(getStepsAttrName(), builder.getI64ArrayAttr(steps));
   result.addOperands(lbArgs);
   result.addOperands(ubArgs);
@@ -2790,7 +2791,6 @@ OpBuilder AffineParallelOp::getBodyBuilder() {
 void AffineParallelOp::setLowerBounds(ValueRange lbOperands, AffineMap map) {
   assert(lbOperands.size() == map.getNumInputs() &&
          "operands to map must match number of inputs");
-  assert(map.getNumResults() >= 1 && "bounds map has at least one result");
 
   auto ubOperands = getUpperBoundsOperands();
 
@@ -2804,7 +2804,6 @@ void AffineParallelOp::setLowerBounds(ValueRange lbOperands, AffineMap map) {
 void AffineParallelOp::setUpperBounds(ValueRange ubOperands, AffineMap map) {
   assert(ubOperands.size() == map.getNumInputs() &&
          "operands to map must match number of inputs");
-  assert(map.getNumResults() >= 1 && "bounds map has at least one result");
 
   SmallVector<Value, 4> newOperands(getLowerBoundsOperands());
   newOperands.append(ubOperands.begin(), ubOperands.end());
@@ -3062,7 +3061,7 @@ static ParseResult parseAffineMapWithMinMax(OpAsmParser &parser,
   if (succeeded(parser.parseOptionalRParen())) {
     result.addAttribute(
         mapName, AffineMapAttr::get(parser.getBuilder().getEmptyAffineMap()));
-    result.addAttribute(groupsName, parser.getBuilder().getI32VectorAttr({}));
+    result.addAttribute(groupsName, parser.getBuilder().getI32TensorAttr({}));
     return success();
   }
 
@@ -3134,7 +3133,7 @@ static ParseResult parseAffineMapWithMinMax(OpAsmParser &parser,
       dimRplacements, symRepacements, dimOperands.size(), symOperands.size());
 
   result.addAttribute(mapName, AffineMapAttr::get(flatMap));
-  result.addAttribute(groupsName, builder.getI32VectorAttr(numMapsPerGroup));
+  result.addAttribute(groupsName, builder.getI32TensorAttr(numMapsPerGroup));
   return success();
 }
 

diff  --git a/mlir/test/Dialect/Affine/ops.mlir b/mlir/test/Dialect/Affine/ops.mlir
index 75b821b25454..358d08a0298b 100644
--- a/mlir/test/Dialect/Affine/ops.mlir
+++ b/mlir/test/Dialect/Affine/ops.mlir
@@ -184,6 +184,17 @@ func @parallel_min_max(%a: index, %b: index, %c: index, %d: index) {
 
 // -----
 
+// CHECK-LABEL: @parallel_no_ivs
+func @parallel_no_ivs() {
+  // CHECK: affine.parallel () = () to ()
+  affine.parallel () = () to () {
+    affine.yield
+  }
+  return
+}
+
+// -----
+
 // CHECK-LABEL: func @affine_if
 func @affine_if() -> f32 {
   // CHECK: %[[ZERO:.*]] = constant {{.*}} : f32


        


More information about the Mlir-commits mailing list