[Mlir-commits] [mlir] Fix assertion when tiling linalg.generic (PR #114688)

Siddhesh Deodhar llvmlistbot at llvm.org
Sat Nov 2 16:21:07 PDT 2024


https://github.com/siddhesh195 created https://github.com/llvm/llvm-project/pull/114688

This patch fixes assertion during tiling due to unsupported linalg.generic containing negative coefficients in indexing expressions by adding a check before attempting tiling

Closes #113021 

>From b2bc3ef80b3c6f14acc5ee2d456e7f6d4f851b65 Mon Sep 17 00:00:00 2001
From: Siddhesh Deodhar <siddheshdeodhar95 at gmail.com>
Date: Sat, 2 Nov 2024 19:17:05 -0400
Subject: [PATCH] Fix assertion when tiling linalg.generic

Fix assertion during tiling due to unsupported linalg.generic containing negative coefficients
---
 mlir/include/mlir/IR/AffineMap.h              |  3 ++
 .../Linalg/Transforms/TilingInterfaceImpl.cpp |  8 +++++
 mlir/lib/IR/AffineMap.cpp                     | 23 +++++++++++++++
 mlir/test/Dialect/Linalg/tile-invalid.mlir    | 29 +++++++++++++++++++
 4 files changed, 63 insertions(+)
 create mode 100644 mlir/test/Dialect/Linalg/tile-invalid.mlir

diff --git a/mlir/include/mlir/IR/AffineMap.h b/mlir/include/mlir/IR/AffineMap.h
index e30950bbf292d6..c2bf0d6b91fed4 100644
--- a/mlir/include/mlir/IR/AffineMap.h
+++ b/mlir/include/mlir/IR/AffineMap.h
@@ -382,6 +382,9 @@ class AffineMap {
   /// Returns true if the AffineMap represents a symbol-less permutation map.
   bool isPermutation() const;
 
+  /// Returns true if the AffineMap contains non-positive coefficients
+  bool isNonPositiveCoefficients() const;
+
   /// Returns the map consisting of the `resultPos` subset.
   AffineMap getSubMap(ArrayRef<unsigned> resultPos) const;
 
diff --git a/mlir/lib/Dialect/Linalg/Transforms/TilingInterfaceImpl.cpp b/mlir/lib/Dialect/Linalg/Transforms/TilingInterfaceImpl.cpp
index f86715a94b268a..b1e1bf9f721fef 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/TilingInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/TilingInterfaceImpl.cpp
@@ -119,6 +119,14 @@ struct LinalgOpTilingInterface
     // specified could lead to out of bounds accesses.
     Location loc = op->getLoc();
     LinalgOp linalgOp = cast<LinalgOp>(op);
+    SmallVector<AffineMap> indexingMaps = linalgOp.getIndexingMapsArray();
+    if (llvm::any_of(linalgOp.getIndexingMapsArray(), [](AffineMap m) {
+          return m.isNonPositiveCoefficients();
+        })) {
+      return linalgOp.emitOpError(
+          "tiling not supported because op has a non positive coefficient");
+    }
+
     SmallVector<Value> valuesToTile = linalgOp->getOperands();
     SmallVector<Value> tiledOperands = makeTiledShapes(
         b, loc, linalgOp, valuesToTile, offsets, sizes, {}, true);
diff --git a/mlir/lib/IR/AffineMap.cpp b/mlir/lib/IR/AffineMap.cpp
index ea3c0723b07759..63a2506552b28c 100644
--- a/mlir/lib/IR/AffineMap.cpp
+++ b/mlir/lib/IR/AffineMap.cpp
@@ -9,6 +9,7 @@
 #include "mlir/IR/AffineMap.h"
 #include "AffineMapDetail.h"
 #include "mlir/IR/AffineExpr.h"
+#include "mlir/IR/AffineExprVisitor.h"
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/BuiltinAttributes.h"
 #include "mlir/IR/BuiltinTypes.h"
@@ -651,6 +652,28 @@ bool AffineMap::isPermutation() const {
   return isProjectedPermutation();
 }
 
+struct CheckCoefficients : public AffineExprVisitor<CheckCoefficients> {
+  CheckCoefficients() {}
+
+  void visitAffineBinaryOpExpr(AffineBinaryOpExpr expr) {
+    visit(expr.getLHS());
+    visit(expr.getRHS());
+    if (expr.getKind() == mlir::AffineExprKind::Mul)
+      isNonPositiveCoefficients |=
+          cast<AffineConstantExpr>(expr.getRHS()).getValue() <= 0;
+  }
+  bool isNonPositiveCoefficients = false;
+};
+
+bool AffineMap::isNonPositiveCoefficients() const {
+
+  return llvm::any_of(getResults(), [](AffineExpr e) {
+    CheckCoefficients t;
+    t.visit(e);
+    return t.isNonPositiveCoefficients;
+  });
+}
+
 AffineMap AffineMap::getSubMap(ArrayRef<unsigned> resultPos) const {
   SmallVector<AffineExpr, 4> exprs;
   exprs.reserve(resultPos.size());
diff --git a/mlir/test/Dialect/Linalg/tile-invalid.mlir b/mlir/test/Dialect/Linalg/tile-invalid.mlir
new file mode 100644
index 00000000000000..1684b1de72c264
--- /dev/null
+++ b/mlir/test/Dialect/Linalg/tile-invalid.mlir
@@ -0,0 +1,29 @@
+// RUN: mlir-opt %s -transform-interpreter -split-input-file -verify-diagnostics
+
+#map1 = affine_map<(d0) -> (d0)>
+#map2 = affine_map<(d0) -> (-d0 + 7)>
+
+func.func @test(%arg0: tensor<8xi8>, %arg1: tensor<8xi8>) -> tensor<8xi8> {
+   // expected-error @below{{tiling not supported because op has a non positive coefficient}}
+   // expected-error @below{{op faild to tile operation}}
+   // expected-error @below{{op failed to generate tiling loops}}
+  %0 = linalg.generic {
+    indexing_maps = [#map2, #map1],
+    iterator_types = ["parallel"]}
+  ins(%arg0 : tensor<8xi8>)
+  outs(%arg1 : tensor<8xi8>) {
+  ^bb0(%in: i8, %out: i8):
+    linalg.yield %in : i8
+  } -> tensor<8xi8>
+  return %0 : tensor<8xi8>
+}
+
+
+module attributes {transform.with_named_sequence} {
+  transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {
+    %0 = transform.structured.match ops{["linalg.generic"]} in %arg1 : (!transform.any_op) -> !transform.any_op
+    %1:2 = transform.structured.tile_using_for
+      %0 tile_sizes [2] : (!transform.any_op) -> (!transform.any_op, !transform.any_op)
+     transform.yield
+  }
+}



More information about the Mlir-commits mailing list