[Mlir-commits] [mlir] [mlir][sparse]Make isBlockSparsity more robust (PR #75113)
Yinying Li
llvmlistbot at llvm.org
Mon Dec 11 15:44:46 PST 2023
https://github.com/yinying-lisa-li updated https://github.com/llvm/llvm-project/pull/75113
>From d85c5f99e39ccca6e80f43dc49f773c80643c363 Mon Sep 17 00:00:00 2001
From: Yinying Li <yinyingli at google.com>
Date: Mon, 11 Dec 2023 23:01:44 +0000
Subject: [PATCH 1/2] [mlir][sparse]Make isBlockSparsity more robust
---
.../SparseTensor/IR/SparseTensorDialect.cpp | 17 ++++++-
.../SparseTensor/invalid_encoding.mlir | 45 +++++++++++++++++++
2 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp b/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
index 686180c09da724..70f508827e26b4 100644
--- a/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
+++ b/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
@@ -855,16 +855,21 @@ SmallVector<unsigned> mlir::sparse_tensor::getBlockSize(AffineMap dimToLvl) {
bool mlir::sparse_tensor::isBlockSparsity(AffineMap dimToLvl) {
if (!dimToLvl)
return false;
+ SmallVector<unsigned> isDimSet;
+ isDimSet.resize(dimToLvl.getNumDims());
std::map<unsigned, int64_t> coeffientMap;
for (auto result : dimToLvl.getResults()) {
if (auto binOp = dyn_cast<AffineBinaryOpExpr>(result)) {
// Check for "dim op const".
auto dimOp = dyn_cast<AffineDimExpr>(binOp.getLHS());
auto conOp = dyn_cast<AffineConstantExpr>(binOp.getRHS());
- if (!dimOp || !conOp)
+ if (!dimOp || !conOp || conOp.getValue() <= 0)
return false;
- // Inspect "dim / const" or "dim % const".
auto pos = dimOp.getPosition();
+ // Check current dim has not been set before.
+ if (isDimSet[pos] == 1)
+ return false;
+ // Inspect "dim / const" or "dim % const".
if (binOp.getKind() == AffineExprKind::FloorDiv) {
// Expect only one floordiv for each dimension.
if (coeffientMap.find(pos) != coeffientMap.end())
@@ -881,6 +886,14 @@ bool mlir::sparse_tensor::isBlockSparsity(AffineMap dimToLvl) {
} else {
return false;
}
+ } else if (auto dimOp = dyn_cast<AffineDimExpr>(result)) {
+ auto pos = dimOp.getPosition();
+ isDimSet[pos] = 1;
+ // Expect dim to be non-blocked (without floordiv/mod pair).
+ if (coeffientMap.find(pos) != coeffientMap.end())
+ return false;
+ } else {
+ return false;
}
}
return !coeffientMap.empty();
diff --git a/mlir/test/Dialect/SparseTensor/invalid_encoding.mlir b/mlir/test/Dialect/SparseTensor/invalid_encoding.mlir
index 6514391bae92d9..2d189cc94c15e2 100644
--- a/mlir/test/Dialect/SparseTensor/invalid_encoding.mlir
+++ b/mlir/test/Dialect/SparseTensor/invalid_encoding.mlir
@@ -254,6 +254,51 @@ func.func private @wrong_order_lvl_decl(%arg0: tensor<?x?xf64, #WrongOrderLvlDec
// -----
+// expected-error at +1 {{failed to infer lvlToDim from dimToLvl}}
+#BSR = #sparse_tensor.encoding<{
+ map = ( i, j ) ->
+ ( i floordiv 2 : dense,
+ j floordiv 3 : compressed,
+ i : dense,
+ j mod 3 : dense
+ )
+}>
+func.func private @BSR(%arg0: tensor<?x?xf64, #BSR>) {
+ return
+}
+
+// -----
+
+// expected-error at +1 {{failed to infer lvlToDim from dimToLvl}}
+#BSR = #sparse_tensor.encoding<{
+ map = ( i, j ) ->
+ ( i : dense,
+ j floordiv 3 : compressed,
+ i floordiv 3 : dense,
+ j mod 3 : dense
+ )
+}>
+func.func private @BSR(%arg0: tensor<?x?xf64, #BSR>) {
+ return
+}
+
+// -----
+
+// expected-error at +1 {{failed to infer lvlToDim from dimToLvl}}
+#BSR = #sparse_tensor.encoding<{
+ map = ( i, j ) ->
+ ( i floordiv -3 : dense,
+ j floordiv -3 : compressed,
+ i mod 3 : dense,
+ j mod 3 : dense
+ )
+}>
+func.func private @BSR(%arg0: tensor<?x?xf64, #BSR>) {
+ return
+}
+
+// -----
+
// expected-error at +1 {{expected lvlToDim to be an inverse of dimToLvl}}
#BSR_explicit = #sparse_tensor.encoding<{
map =
>From 5933b1008a441fbce04767f827302968790e3744 Mon Sep 17 00:00:00 2001
From: Yinying Li <yinyingli at google.com>
Date: Mon, 11 Dec 2023 23:44:25 +0000
Subject: [PATCH 2/2] address comments
---
.../SparseTensor/IR/SparseTensorDialect.cpp | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp b/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
index 70f508827e26b4..622ed13422b84a 100644
--- a/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
+++ b/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
@@ -855,9 +855,8 @@ SmallVector<unsigned> mlir::sparse_tensor::getBlockSize(AffineMap dimToLvl) {
bool mlir::sparse_tensor::isBlockSparsity(AffineMap dimToLvl) {
if (!dimToLvl)
return false;
- SmallVector<unsigned> isDimSet;
- isDimSet.resize(dimToLvl.getNumDims());
std::map<unsigned, int64_t> coeffientMap;
+ bool hasBlock = false;
for (auto result : dimToLvl.getResults()) {
if (auto binOp = dyn_cast<AffineBinaryOpExpr>(result)) {
// Check for "dim op const".
@@ -865,11 +864,8 @@ bool mlir::sparse_tensor::isBlockSparsity(AffineMap dimToLvl) {
auto conOp = dyn_cast<AffineConstantExpr>(binOp.getRHS());
if (!dimOp || !conOp || conOp.getValue() <= 0)
return false;
- auto pos = dimOp.getPosition();
- // Check current dim has not been set before.
- if (isDimSet[pos] == 1)
- return false;
// Inspect "dim / const" or "dim % const".
+ auto pos = dimOp.getPosition();
if (binOp.getKind() == AffineExprKind::FloorDiv) {
// Expect only one floordiv for each dimension.
if (coeffientMap.find(pos) != coeffientMap.end())
@@ -883,20 +879,21 @@ bool mlir::sparse_tensor::isBlockSparsity(AffineMap dimToLvl) {
// Expect mod to have the same coefficient as floordiv.
if (conOp.getValue() != coeffientMap[pos])
return false;
+ hasBlock = true;
} else {
return false;
}
} else if (auto dimOp = dyn_cast<AffineDimExpr>(result)) {
auto pos = dimOp.getPosition();
- isDimSet[pos] = 1;
- // Expect dim to be non-blocked (without floordiv/mod pair).
+ // Expect dim to be unset.
if (coeffientMap.find(pos) != coeffientMap.end())
return false;
+ coeffientMap[pos] = 0;
} else {
return false;
}
}
- return !coeffientMap.empty();
+ return !coeffientMap.empty() && hasBlock;
}
bool mlir::sparse_tensor::hasAnyNonIdentityOperandsOrResults(Operation *op) {
More information about the Mlir-commits
mailing list