Skip to content

Commit b2bc3ef

Browse files
committed
Fix assertion when tiling linalg.generic
Fix assertion during tiling due to unsupported linalg.generic containing negative coefficients
1 parent 7a90ff7 commit b2bc3ef

File tree

4 files changed

+63
-0
lines changed

4 files changed

+63
-0
lines changed

mlir/include/mlir/IR/AffineMap.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,9 @@ class AffineMap {
382382
/// Returns true if the AffineMap represents a symbol-less permutation map.
383383
bool isPermutation() const;
384384

385+
/// Returns true if the AffineMap contains non-positive coefficients
386+
bool isNonPositiveCoefficients() const;
387+
385388
/// Returns the map consisting of the `resultPos` subset.
386389
AffineMap getSubMap(ArrayRef<unsigned> resultPos) const;
387390

mlir/lib/Dialect/Linalg/Transforms/TilingInterfaceImpl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ struct LinalgOpTilingInterface
119119
// specified could lead to out of bounds accesses.
120120
Location loc = op->getLoc();
121121
LinalgOp linalgOp = cast<LinalgOp>(op);
122+
SmallVector<AffineMap> indexingMaps = linalgOp.getIndexingMapsArray();
123+
if (llvm::any_of(linalgOp.getIndexingMapsArray(), [](AffineMap m) {
124+
return m.isNonPositiveCoefficients();
125+
})) {
126+
return linalgOp.emitOpError(
127+
"tiling not supported because op has a non positive coefficient");
128+
}
129+
122130
SmallVector<Value> valuesToTile = linalgOp->getOperands();
123131
SmallVector<Value> tiledOperands = makeTiledShapes(
124132
b, loc, linalgOp, valuesToTile, offsets, sizes, {}, true);

mlir/lib/IR/AffineMap.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "mlir/IR/AffineMap.h"
1010
#include "AffineMapDetail.h"
1111
#include "mlir/IR/AffineExpr.h"
12+
#include "mlir/IR/AffineExprVisitor.h"
1213
#include "mlir/IR/Builders.h"
1314
#include "mlir/IR/BuiltinAttributes.h"
1415
#include "mlir/IR/BuiltinTypes.h"
@@ -651,6 +652,28 @@ bool AffineMap::isPermutation() const {
651652
return isProjectedPermutation();
652653
}
653654

655+
struct CheckCoefficients : public AffineExprVisitor<CheckCoefficients> {
656+
CheckCoefficients() {}
657+
658+
void visitAffineBinaryOpExpr(AffineBinaryOpExpr expr) {
659+
visit(expr.getLHS());
660+
visit(expr.getRHS());
661+
if (expr.getKind() == mlir::AffineExprKind::Mul)
662+
isNonPositiveCoefficients |=
663+
cast<AffineConstantExpr>(expr.getRHS()).getValue() <= 0;
664+
}
665+
bool isNonPositiveCoefficients = false;
666+
};
667+
668+
bool AffineMap::isNonPositiveCoefficients() const {
669+
670+
return llvm::any_of(getResults(), [](AffineExpr e) {
671+
CheckCoefficients t;
672+
t.visit(e);
673+
return t.isNonPositiveCoefficients;
674+
});
675+
}
676+
654677
AffineMap AffineMap::getSubMap(ArrayRef<unsigned> resultPos) const {
655678
SmallVector<AffineExpr, 4> exprs;
656679
exprs.reserve(resultPos.size());
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: mlir-opt %s -transform-interpreter -split-input-file -verify-diagnostics
2+
3+
#map1 = affine_map<(d0) -> (d0)>
4+
#map2 = affine_map<(d0) -> (-d0 + 7)>
5+
6+
func.func @test(%arg0: tensor<8xi8>, %arg1: tensor<8xi8>) -> tensor<8xi8> {
7+
// expected-error @below{{tiling not supported because op has a non positive coefficient}}
8+
// expected-error @below{{op faild to tile operation}}
9+
// expected-error @below{{op failed to generate tiling loops}}
10+
%0 = linalg.generic {
11+
indexing_maps = [#map2, #map1],
12+
iterator_types = ["parallel"]}
13+
ins(%arg0 : tensor<8xi8>)
14+
outs(%arg1 : tensor<8xi8>) {
15+
^bb0(%in: i8, %out: i8):
16+
linalg.yield %in : i8
17+
} -> tensor<8xi8>
18+
return %0 : tensor<8xi8>
19+
}
20+
21+
22+
module attributes {transform.with_named_sequence} {
23+
transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {
24+
%0 = transform.structured.match ops{["linalg.generic"]} in %arg1 : (!transform.any_op) -> !transform.any_op
25+
%1:2 = transform.structured.tile_using_for
26+
%0 tile_sizes [2] : (!transform.any_op) -> (!transform.any_op, !transform.any_op)
27+
transform.yield
28+
}
29+
}

0 commit comments

Comments
 (0)