[Mlir-commits] [mlir] f934db3 - [mlir][sparse] Reject dense level after non-unique level in encoding verifier (#184157)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Mar 3 03:42:53 PST 2026
Author: Mehdi Amini
Date: 2026-03-03T12:42:49+01:00
New Revision: f934db36aa2606054b3e73af7258df3fd8ccdb64
URL: https://github.com/llvm/llvm-project/commit/f934db36aa2606054b3e73af7258df3fd8ccdb64
DIFF: https://github.com/llvm/llvm-project/commit/f934db36aa2606054b3e73af7258df3fd8ccdb64.diff
LOG: [mlir][sparse] Reject dense level after non-unique level in encoding verifier (#184157)
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
Added:
Modified:
mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
mlir/test/Dialect/SparseTensor/invalid_encoding.mlir
Removed:
################################################################################
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)
More information about the Mlir-commits
mailing list