[Mlir-commits] [mlir] [mlir][sparse] Reject dense level after non-unique level in encoding verifier (PR #184157)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Mar 2 07:43:28 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-sparse
Author: Mehdi Amini (joker-eph)
<details>
<summary>Changes</summary>
The sparse tensor iteration model for dense levels requires exactly one parent position to linearize into a contiguous range. However, when a non-unique level (e.g. compressed(nonunique)) precedes a dense level, the DedupIterator provides a two-element cursor {posLo, segHi}, causing DenseLevel::peekRangeAt to assert and crash with:
Assertion `parentPos.size() == 1 && "Dense level can not be non-unique."'
Fix this by adding a check in SparseTensorEncodingAttr::verify that rejects any encoding where a dense level directly follows a non-unique level, emitting a proper diagnostic instead of crashing during lowering.
Fixes #<!-- -->130008
---
Full diff: https://github.com/llvm/llvm-project/pull/184157.diff
2 Files Affected:
- (modified) mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp (+9)
- (modified) mlir/test/Dialect/SparseTensor/invalid_encoding.mlir (+11)
``````````diff
diff --git a/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp b/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
index 3a34ad90941b0..05b2e07b88ba5 100644
--- a/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
+++ b/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
@@ -826,6 +826,15 @@ LogicalResult SparseTensorEncodingAttr::verify(
return emitError() << "SoA is only applicable to singleton lvlTypes.";
}
+ // Dense levels cannot follow a non-unique level. The iteration model for
+ // dense levels requires exactly one parent position to linearize into a
+ // contiguous range, but a non-unique parent provides two cursor values
+ // (segment start and end), which the dense level cannot handle.
+ for (auto [i, lt] : llvm::drop_begin(llvm::enumerate(lvlTypes))) {
+ if (isDenseLT(lt) && !isUniqueLT(lvlTypes[i - 1]))
+ return emitError() << "dense level cannot follow a non-unique level";
+ }
+
// TODO: audit formats that actually are supported by backend.
if (auto it = llvm::find_if(lvlTypes, isNOutOfMLT);
it != std::end(lvlTypes)) {
diff --git a/mlir/test/Dialect/SparseTensor/invalid_encoding.mlir b/mlir/test/Dialect/SparseTensor/invalid_encoding.mlir
index a3f72bd3ae971..0d0234149fb3e 100644
--- a/mlir/test/Dialect/SparseTensor/invalid_encoding.mlir
+++ b/mlir/test/Dialect/SparseTensor/invalid_encoding.mlir
@@ -256,6 +256,17 @@ func.func private @sparse_coo(tensor<?x?xf32, #COO_SoA>)
// -----
+// expected-error at +1{{dense level cannot follow a non-unique level}}
+#COO_Dense = #sparse_tensor.encoding<{
+ map = (i, j) -> (
+ i : compressed(nonunique),
+ j : dense
+ )
+}>
+func.func private @dense_after_nonunique(tensor<?x?xf32, #COO_Dense>)
+
+// -----
+
// expected-error at +2 {{use of undeclared identifier 'l1'}}
#TooFewLvlDecl = #sparse_tensor.encoding<{
map = {l0} (d0, d1) -> (l0 = d0 : dense, l1 = d1 : compressed)
``````````
</details>
https://github.com/llvm/llvm-project/pull/184157
More information about the Mlir-commits
mailing list