[Mlir-commits] [mlir] [MLIR][SparseTensor] Loop ordering strategy infrastructure (flag) (PR #154656)
Govind Malasani
llvmlistbot at llvm.org
Fri Sep 26 20:36:49 PDT 2025
https://github.com/gmalasan updated https://github.com/llvm/llvm-project/pull/154656
>From b9ae6210b4a6a5617e923df9c1bcee1f4e19c2c0 Mon Sep 17 00:00:00 2001
From: gmalasan <145235389+gmalasan at users.noreply.github.com>
Date: Wed, 20 Aug 2025 18:07:07 -0700
Subject: [PATCH 1/7] [MLIR][SparseTensor] Loop ordering strategy
infrastructure (flag)
---
.../mlir/Dialect/SparseTensor/Transforms/Passes.h | 14 +++++++++++++-
.../mlir/Dialect/SparseTensor/Transforms/Passes.td | 5 +++++
.../Transforms/SparseReinterpretMap.cpp | 5 ++++-
.../SparseTensor/Transforms/SparseTensorPasses.cpp | 12 +++++++++++-
4 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h b/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h
index 212f7b6f13c26..24f30353e58b5 100644
--- a/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h
+++ b/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h
@@ -55,6 +55,15 @@ enum class SparseEmitStrategy {
kDebugInterface, // generate only place-holder for sparse iteration
};
+namespace sparse_tensor {
+
+/// Selects between different loop ordering strategies for sparse tensor
+enum class LoopOrderingStrategy : unsigned {
+ kDefault, ///< Default strategy (current behavior)
+};
+
+} // namespace sparse_tensor
+
#define GEN_PASS_DECL
#include "mlir/Dialect/SparseTensor/Transforms/Passes.h.inc"
@@ -72,10 +81,13 @@ std::unique_ptr<Pass> createSparseAssembler(bool directOut);
//===----------------------------------------------------------------------===//
void populateSparseReinterpretMap(RewritePatternSet &patterns,
- ReinterpretMapScope scope);
+ ReinterpretMapScope scope,
+ sparse_tensor::LoopOrderingStrategy strategy = sparse_tensor::LoopOrderingStrategy::kDefault);
std::unique_ptr<Pass> createSparseReinterpretMapPass();
std::unique_ptr<Pass> createSparseReinterpretMapPass(ReinterpretMapScope scope);
+std::unique_ptr<Pass> createSparseReinterpretMapPass(ReinterpretMapScope scope,
+ sparse_tensor::LoopOrderingStrategy strategy);
//===----------------------------------------------------------------------===//
// The PreSparsificationRewriting pass.
diff --git a/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td b/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td
index 2513e106f5b06..1b0c7f7583827 100644
--- a/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td
+++ b/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td
@@ -81,6 +81,11 @@ def SparseReinterpretMap : Pass<"sparse-reinterpret-map", "ModuleOp"> {
clEnumValN(mlir::ReinterpretMapScope::kExceptGeneric,
"except-generic",
"Run on operations expect linalg.generic (e.g., foreach)"))}]>,
+ Option<"loopOrderingStrategy", "loop-ordering-strategy", "mlir::sparse_tensor::LoopOrderingStrategy",
+ "mlir::sparse_tensor::LoopOrderingStrategy::kDefault",
+ "Set the loop ordering strategy for sparse tensor dialect", [{llvm::cl::values(
+ clEnumValN(mlir::sparse_tensor::LoopOrderingStrategy::kDefault, "default",
+ "Default strategy (current behavior)"))}]>,
];
}
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
index df9b6cf040efa..06c58d2b13cf2 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
@@ -788,7 +788,10 @@ struct ForeachOpDemapper
} // namespace
void mlir::populateSparseReinterpretMap(RewritePatternSet &patterns,
- ReinterpretMapScope scope) {
+ ReinterpretMapScope scope,
+ sparse_tensor::LoopOrderingStrategy strategy) {
+ (void)strategy; // Suppress unused parameter warning
+
if (scope == ReinterpretMapScope::kAll ||
scope == ReinterpretMapScope::kGenericOnly) {
patterns.add<GenericOpReinterpretMap, GenericOpScheduler>(
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorPasses.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorPasses.cpp
index 153b9b170e5d3..aa31927e0602c 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorPasses.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorPasses.cpp
@@ -67,12 +67,13 @@ struct SparseReinterpretMap
SparseReinterpretMap(const SparseReinterpretMap &pass) = default;
SparseReinterpretMap(const SparseReinterpretMapOptions &options) {
scope = options.scope;
+ loopOrderingStrategy = options.loopOrderingStrategy;
}
void runOnOperation() override {
auto *ctx = &getContext();
RewritePatternSet patterns(ctx);
- populateSparseReinterpretMap(patterns, scope);
+ populateSparseReinterpretMap(patterns, scope, loopOrderingStrategy);
(void)applyPatternsGreedily(getOperation(), std::move(patterns));
}
};
@@ -438,6 +439,15 @@ mlir::createSparseReinterpretMapPass(ReinterpretMapScope scope) {
return std::make_unique<SparseReinterpretMap>(options);
}
+std::unique_ptr<Pass>
+mlir::createSparseReinterpretMapPass(ReinterpretMapScope scope,
+ sparse_tensor::LoopOrderingStrategy strategy) {
+ SparseReinterpretMapOptions options;
+ options.scope = scope;
+ options.loopOrderingStrategy = strategy;
+ return std::make_unique<SparseReinterpretMap>(options);
+}
+
std::unique_ptr<Pass> mlir::createPreSparsificationRewritePass() {
return std::make_unique<PreSparsificationRewritePass>();
}
>From 97cec4ebc9aab512fde4c3515225f2bab65aa3bc Mon Sep 17 00:00:00 2001
From: gmalasan <145235389+gmalasan at users.noreply.github.com>
Date: Wed, 20 Aug 2025 18:36:51 -0700
Subject: [PATCH 2/7] [MLIR][SparseTensor] Fixed up the rest of the boilerplate
code, strategy fully available in the topoSort method in IterationGraphSorter
---
.../Transforms/SparseReinterpretMap.cpp | 16 +++++++++------
.../Transforms/Utils/IterationGraphSorter.cpp | 20 ++++++++++++++-----
.../Transforms/Utils/IterationGraphSorter.h | 12 ++++++++---
3 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
index 06c58d2b13cf2..bf3b02829175f 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
@@ -408,7 +408,9 @@ struct GenericOpReinterpretMap
};
struct GenericOpScheduler : public OpRewritePattern<linalg::GenericOp> {
- using OpRewritePattern::OpRewritePattern;
+ GenericOpScheduler(MLIRContext *context, sparse_tensor::LoopOrderingStrategy strategy)
+ : OpRewritePattern<linalg::GenericOp>(context), strategy(strategy) {}
+
LogicalResult matchAndRewrite(linalg::GenericOp linalgOp,
PatternRewriter &rewriter) const override {
if (linalgOp.getNumDpsInits() != 1 || !linalgOp.hasPureTensorSemantics() ||
@@ -421,7 +423,8 @@ struct GenericOpScheduler : public OpRewritePattern<linalg::GenericOp> {
if (linalgOp->hasAttr(sorted))
return failure();
- auto scheduler = IterationGraphSorter::fromGenericOp(linalgOp);
+ // Pass strategy to IterationGraphSorter
+ auto scheduler = IterationGraphSorter::fromGenericOp(linalgOp, strategy);
bool isAdmissible = false;
AffineMap order;
// A const list of all masks that we used for iteration graph
@@ -583,6 +586,9 @@ struct GenericOpScheduler : public OpRewritePattern<linalg::GenericOp> {
// TODO: convert more than one?
return failure();
}
+
+private:
+ sparse_tensor::LoopOrderingStrategy strategy;
};
//===----------------------------------------------------------------------===//
@@ -790,12 +796,10 @@ struct ForeachOpDemapper
void mlir::populateSparseReinterpretMap(RewritePatternSet &patterns,
ReinterpretMapScope scope,
sparse_tensor::LoopOrderingStrategy strategy) {
- (void)strategy; // Suppress unused parameter warning
-
if (scope == ReinterpretMapScope::kAll ||
scope == ReinterpretMapScope::kGenericOnly) {
- patterns.add<GenericOpReinterpretMap, GenericOpScheduler>(
- patterns.getContext());
+ patterns.add<GenericOpReinterpretMap>(patterns.getContext());
+ patterns.add<GenericOpScheduler>(patterns.getContext(), strategy);
}
if (scope == ReinterpretMapScope::kAll ||
scope == ReinterpretMapScope::kExceptGeneric) {
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp
index c7e463a5a5b49..6cebb4bcdc3c3 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp
@@ -100,7 +100,15 @@ AffineMap IterationGraphSorter::topoSort() {
// We always prefer a parallel loop over a reduction loop because putting
// a reduction loop early might make the loop sequence inadmissible.
auto &it = !parIt.empty() ? parIt : redIt;
- auto src = it.back();
+
+ // Select loop based on strategy
+ unsigned src;
+ switch (strategy) {
+ case sparse_tensor::LoopOrderingStrategy::kDefault:
+ src = it.back();
+ break;
+ }
+
loopOrder.push_back(src);
it.pop_back();
// Update in-degree, and push 0-degree node into worklist.
@@ -123,7 +131,8 @@ AffineMap IterationGraphSorter::topoSort() {
}
IterationGraphSorter
-IterationGraphSorter::fromGenericOp(linalg::GenericOp genericOp) {
+IterationGraphSorter::fromGenericOp(linalg::GenericOp genericOp,
+ sparse_tensor::LoopOrderingStrategy strategy) {
// Must be a demapped sparse kernel.
assert(!hasAnyNonIdentityOperandsOrResults(genericOp) &&
hasAnySparseOperandOrResult(genericOp) &&
@@ -140,14 +149,15 @@ IterationGraphSorter::fromGenericOp(linalg::GenericOp genericOp) {
genericOp.getIteratorTypesArray();
return IterationGraphSorter(std::move(ins), std::move(loopMap), out, outMap,
- std::move(iterTypes));
+ std::move(iterTypes), strategy);
}
IterationGraphSorter::IterationGraphSorter(
SmallVector<Value> &&ins, SmallVector<AffineMap> &&loop2InsLvl, Value out,
- AffineMap loop2OutLvl, SmallVector<utils::IteratorType> &&iterTypes)
+ AffineMap loop2OutLvl, SmallVector<utils::IteratorType> &&iterTypes,
+ sparse_tensor::LoopOrderingStrategy strategy)
: ins(std::move(ins)), loop2InsLvl(std::move(loop2InsLvl)), out(out),
- loop2OutLvl(loop2OutLvl), iterTypes(std::move(iterTypes)) {
+ loop2OutLvl(loop2OutLvl), iterTypes(std::move(iterTypes)), strategy(strategy) {
// One map per tensor.
assert(loop2InsLvl.size() == ins.size());
// All the affine maps have the same number of dimensions (loops).
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h
index a6abe9eb76c47..a4902d31e0077 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h
@@ -14,6 +14,7 @@
#define MLIR_DIALECT_SPARSETENSOR_TRANSFORMS_UTILS_ITERATIONGRAPHSORTER_H_
#include "mlir/IR/AffineMap.h"
+#include "mlir/Dialect/SparseTensor/Transforms/Passes.h"
namespace mlir {
@@ -42,8 +43,9 @@ enum class SortMask : unsigned {
class IterationGraphSorter {
public:
/// Factory method that construct an iteration graph sorter
- /// for the given linalg.generic operation.
- static IterationGraphSorter fromGenericOp(linalg::GenericOp genericOp);
+ /// for the given linalg.generic operation with a specific strategy.
+ static IterationGraphSorter fromGenericOp(linalg::GenericOp genericOp,
+ sparse_tensor::LoopOrderingStrategy strategy);
/// Returns a permutation that represents the scheduled loop order.
/// Note that the returned AffineMap could be null if the kernel
@@ -58,7 +60,8 @@ class IterationGraphSorter {
IterationGraphSorter(SmallVector<Value> &&ins,
SmallVector<AffineMap> &&loop2InsLvl, Value out,
AffineMap loop2OutLvl,
- SmallVector<utils::IteratorType> &&iterTypes);
+ SmallVector<utils::IteratorType> &&iterTypes,
+ sparse_tensor::LoopOrderingStrategy strategy = sparse_tensor::LoopOrderingStrategy::kDefault);
// Adds all the constraints in the given loop to level map.
void addConstraints(Value t, AffineMap loop2LvlMap);
@@ -84,6 +87,9 @@ class IterationGraphSorter {
// InDegree used for topo sort.
std::vector<unsigned> inDegree;
+
+ // Loop ordering strategy.
+ sparse_tensor::LoopOrderingStrategy strategy;
};
} // namespace sparse_tensor
>From 3f3661ae20542c2107ea23991e0728474106f574 Mon Sep 17 00:00:00 2001
From: gmalasan <145235389+gmalasan at users.noreply.github.com>
Date: Tue, 26 Aug 2025 16:22:54 -0400
Subject: [PATCH 3/7] [MLIR][SparseTensor] Fixed PR feedback about style
---
mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h | 4 ++--
mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td | 4 ++--
.../Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp | 2 +-
.../SparseTensor/Transforms/Utils/IterationGraphSorter.cpp | 2 +-
.../SparseTensor/Transforms/Utils/IterationGraphSorter.h | 2 +-
5 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h b/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h
index 24f30353e58b5..93ff5ce606423 100644
--- a/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h
+++ b/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h
@@ -57,9 +57,9 @@ enum class SparseEmitStrategy {
namespace sparse_tensor {
-/// Selects between different loop ordering strategies for sparse tensor
+/// Defines a strategy for loop ordering during sparse code generation.
enum class LoopOrderingStrategy : unsigned {
- kDefault, ///< Default strategy (current behavior)
+ kDefault, ///< Default strategy (selects loops from back of available candidates).
};
} // namespace sparse_tensor
diff --git a/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td b/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td
index 1b0c7f7583827..91bc4ae8a6bd2 100644
--- a/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td
+++ b/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td
@@ -83,9 +83,9 @@ def SparseReinterpretMap : Pass<"sparse-reinterpret-map", "ModuleOp"> {
"Run on operations expect linalg.generic (e.g., foreach)"))}]>,
Option<"loopOrderingStrategy", "loop-ordering-strategy", "mlir::sparse_tensor::LoopOrderingStrategy",
"mlir::sparse_tensor::LoopOrderingStrategy::kDefault",
- "Set the loop ordering strategy for sparse tensor dialect", [{llvm::cl::values(
+ "Set the loop ordering strategy for sparse code generation", [{llvm::cl::values(
clEnumValN(mlir::sparse_tensor::LoopOrderingStrategy::kDefault, "default",
- "Default strategy (current behavior)"))}]>,
+ "Default strategy (selects loops from back of available candidates)"))}]>,
];
}
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
index bf3b02829175f..5822d0a24bbf1 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
@@ -423,7 +423,7 @@ struct GenericOpScheduler : public OpRewritePattern<linalg::GenericOp> {
if (linalgOp->hasAttr(sorted))
return failure();
- // Pass strategy to IterationGraphSorter
+ // Pass strategy to IterationGraphSorter.
auto scheduler = IterationGraphSorter::fromGenericOp(linalgOp, strategy);
bool isAdmissible = false;
AffineMap order;
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp
index 6cebb4bcdc3c3..29596e5febe1a 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp
@@ -101,7 +101,7 @@ AffineMap IterationGraphSorter::topoSort() {
// a reduction loop early might make the loop sequence inadmissible.
auto &it = !parIt.empty() ? parIt : redIt;
- // Select loop based on strategy
+ // Select loop based on strategy.
unsigned src;
switch (strategy) {
case sparse_tensor::LoopOrderingStrategy::kDefault:
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h
index a4902d31e0077..22c186d563c4a 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h
@@ -43,7 +43,7 @@ enum class SortMask : unsigned {
class IterationGraphSorter {
public:
/// Factory method that construct an iteration graph sorter
- /// for the given linalg.generic operation with a specific strategy.
+ /// for the given linalg.generic operation with a specific loop ordering strategy.
static IterationGraphSorter fromGenericOp(linalg::GenericOp genericOp,
sparse_tensor::LoopOrderingStrategy strategy);
>From d0b96d798706aa89640b8fd34c72d8d6973a36e0 Mon Sep 17 00:00:00 2001
From: gmalasan <145235389+gmalasan at users.noreply.github.com>
Date: Mon, 8 Sep 2025 18:31:08 -0400
Subject: [PATCH 4/7] [MLIR][SparseTensor] Comment style fixes
---
mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td | 2 +-
.../SparseTensor/Transforms/Utils/IterationGraphSorter.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td b/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td
index 91bc4ae8a6bd2..75e77d67db1b3 100644
--- a/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td
+++ b/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td
@@ -85,7 +85,7 @@ def SparseReinterpretMap : Pass<"sparse-reinterpret-map", "ModuleOp"> {
"mlir::sparse_tensor::LoopOrderingStrategy::kDefault",
"Set the loop ordering strategy for sparse code generation", [{llvm::cl::values(
clEnumValN(mlir::sparse_tensor::LoopOrderingStrategy::kDefault, "default",
- "Default strategy (selects loops from back of available candidates)"))}]>,
+ "Default strategy (eagerly selects last loop in topological sort)"))}]>,
];
}
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h
index 22c186d563c4a..868a978e9a462 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h
@@ -42,7 +42,7 @@ enum class SortMask : unsigned {
class IterationGraphSorter {
public:
- /// Factory method that construct an iteration graph sorter
+ /// Factory method that constructs an iteration graph sorter
/// for the given linalg.generic operation with a specific loop ordering strategy.
static IterationGraphSorter fromGenericOp(linalg::GenericOp genericOp,
sparse_tensor::LoopOrderingStrategy strategy);
>From fde6039458a39813519babe2f586cfa07749db32 Mon Sep 17 00:00:00 2001
From: gmalasan <145235389+gmalasan at users.noreply.github.com>
Date: Tue, 9 Sep 2025 17:28:31 -0400
Subject: [PATCH 5/7] [MLIR][SparseTensor] Missed comment style fix in Passes.h
---
mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h b/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h
index 93ff5ce606423..9a966a4ddb8b6 100644
--- a/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h
+++ b/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h
@@ -59,7 +59,7 @@ namespace sparse_tensor {
/// Defines a strategy for loop ordering during sparse code generation.
enum class LoopOrderingStrategy : unsigned {
- kDefault, ///< Default strategy (selects loops from back of available candidates).
+ kDefault, ///< Default strategy (eagerly selects last loop in topological sort).
};
} // namespace sparse_tensor
>From fbfa3b6a004671d8106bbe376c2becb2078bad8f Mon Sep 17 00:00:00 2001
From: gmalasan <145235389+gmalasan at users.noreply.github.com>
Date: Tue, 23 Sep 2025 22:46:01 -0400
Subject: [PATCH 6/7] Apply clang-format to C++ files for loop ordering
infrastructure
---
.../mlir/Dialect/SparseTensor/Transforms/Passes.h | 15 +++++++++------
.../Transforms/SparseReinterpretMap.cpp | 15 ++++++++-------
.../Transforms/Utils/IterationGraphSorter.cpp | 12 ++++++------
.../Transforms/Utils/IterationGraphSorter.h | 13 ++++++++-----
4 files changed, 31 insertions(+), 24 deletions(-)
diff --git a/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h b/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h
index 9a966a4ddb8b6..af64370a62dd7 100644
--- a/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h
+++ b/mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.h
@@ -59,7 +59,8 @@ namespace sparse_tensor {
/// Defines a strategy for loop ordering during sparse code generation.
enum class LoopOrderingStrategy : unsigned {
- kDefault, ///< Default strategy (eagerly selects last loop in topological sort).
+ kDefault, ///< Default strategy (eagerly selects last loop in topological
+ ///< sort).
};
} // namespace sparse_tensor
@@ -80,14 +81,16 @@ std::unique_ptr<Pass> createSparseAssembler(bool directOut);
// The SparseReinterpretMap pass.
//===----------------------------------------------------------------------===//
-void populateSparseReinterpretMap(RewritePatternSet &patterns,
- ReinterpretMapScope scope,
- sparse_tensor::LoopOrderingStrategy strategy = sparse_tensor::LoopOrderingStrategy::kDefault);
+void populateSparseReinterpretMap(
+ RewritePatternSet &patterns, ReinterpretMapScope scope,
+ sparse_tensor::LoopOrderingStrategy strategy =
+ sparse_tensor::LoopOrderingStrategy::kDefault);
std::unique_ptr<Pass> createSparseReinterpretMapPass();
std::unique_ptr<Pass> createSparseReinterpretMapPass(ReinterpretMapScope scope);
-std::unique_ptr<Pass> createSparseReinterpretMapPass(ReinterpretMapScope scope,
- sparse_tensor::LoopOrderingStrategy strategy);
+std::unique_ptr<Pass>
+createSparseReinterpretMapPass(ReinterpretMapScope scope,
+ sparse_tensor::LoopOrderingStrategy strategy);
//===----------------------------------------------------------------------===//
// The PreSparsificationRewriting pass.
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
index e068eee0587a0..0fc5cc76de39c 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
@@ -59,7 +59,7 @@ struct DemapInsRewriter : public OpRewritePattern<SourceOp> {
// Flattens an affine expression into a list of AffineDimExprs.
struct AffineDimCollector : public AffineExprVisitor<AffineDimCollector> {
- explicit AffineDimCollector(unsigned dimNum) : dims(dimNum){};
+ explicit AffineDimCollector(unsigned dimNum) : dims(dimNum) {};
void visitDimExpr(AffineDimExpr expr) { dims.set(expr.getPosition()); }
BitVector dims;
};
@@ -67,7 +67,7 @@ struct AffineDimCollector : public AffineExprVisitor<AffineDimCollector> {
// Flattens an affine expression into a list of AffineDimExprs.
struct AffineExprAdmissibleVisitor
: public AffineExprVisitor<AffineExprAdmissibleVisitor> {
- explicit AffineExprAdmissibleVisitor(bool isOutput) : isOutput(isOutput){};
+ explicit AffineExprAdmissibleVisitor(bool isOutput) : isOutput(isOutput) {};
// We only allow AffineDimExpr on output.
void visitAddExpr(AffineBinaryOpExpr expr) {
@@ -407,9 +407,10 @@ struct GenericOpReinterpretMap
};
struct GenericOpScheduler : public OpRewritePattern<linalg::GenericOp> {
- GenericOpScheduler(MLIRContext *context, sparse_tensor::LoopOrderingStrategy strategy)
+ GenericOpScheduler(MLIRContext *context,
+ sparse_tensor::LoopOrderingStrategy strategy)
: OpRewritePattern<linalg::GenericOp>(context), strategy(strategy) {}
-
+
LogicalResult matchAndRewrite(linalg::GenericOp linalgOp,
PatternRewriter &rewriter) const override {
if (linalgOp.getNumDpsInits() != 1 || !linalgOp.hasPureTensorSemantics() ||
@@ -792,9 +793,9 @@ struct ForeachOpDemapper
} // namespace
-void mlir::populateSparseReinterpretMap(RewritePatternSet &patterns,
- ReinterpretMapScope scope,
- sparse_tensor::LoopOrderingStrategy strategy) {
+void mlir::populateSparseReinterpretMap(
+ RewritePatternSet &patterns, ReinterpretMapScope scope,
+ sparse_tensor::LoopOrderingStrategy strategy) {
if (scope == ReinterpretMapScope::kAll ||
scope == ReinterpretMapScope::kGenericOnly) {
patterns.add<GenericOpReinterpretMap>(patterns.getContext());
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp
index 29596e5febe1a..73e0f3d2891d7 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp
@@ -100,7 +100,7 @@ AffineMap IterationGraphSorter::topoSort() {
// We always prefer a parallel loop over a reduction loop because putting
// a reduction loop early might make the loop sequence inadmissible.
auto &it = !parIt.empty() ? parIt : redIt;
-
+
// Select loop based on strategy.
unsigned src;
switch (strategy) {
@@ -108,7 +108,7 @@ AffineMap IterationGraphSorter::topoSort() {
src = it.back();
break;
}
-
+
loopOrder.push_back(src);
it.pop_back();
// Update in-degree, and push 0-degree node into worklist.
@@ -130,9 +130,8 @@ AffineMap IterationGraphSorter::topoSort() {
return AffineMap();
}
-IterationGraphSorter
-IterationGraphSorter::fromGenericOp(linalg::GenericOp genericOp,
- sparse_tensor::LoopOrderingStrategy strategy) {
+IterationGraphSorter IterationGraphSorter::fromGenericOp(
+ linalg::GenericOp genericOp, sparse_tensor::LoopOrderingStrategy strategy) {
// Must be a demapped sparse kernel.
assert(!hasAnyNonIdentityOperandsOrResults(genericOp) &&
hasAnySparseOperandOrResult(genericOp) &&
@@ -157,7 +156,8 @@ IterationGraphSorter::IterationGraphSorter(
AffineMap loop2OutLvl, SmallVector<utils::IteratorType> &&iterTypes,
sparse_tensor::LoopOrderingStrategy strategy)
: ins(std::move(ins)), loop2InsLvl(std::move(loop2InsLvl)), out(out),
- loop2OutLvl(loop2OutLvl), iterTypes(std::move(iterTypes)), strategy(strategy) {
+ loop2OutLvl(loop2OutLvl), iterTypes(std::move(iterTypes)),
+ strategy(strategy) {
// One map per tensor.
assert(loop2InsLvl.size() == ins.size());
// All the affine maps have the same number of dimensions (loops).
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h
index 868a978e9a462..b2a16e9382758 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h
@@ -13,8 +13,8 @@
#ifndef MLIR_DIALECT_SPARSETENSOR_TRANSFORMS_UTILS_ITERATIONGRAPHSORTER_H_
#define MLIR_DIALECT_SPARSETENSOR_TRANSFORMS_UTILS_ITERATIONGRAPHSORTER_H_
-#include "mlir/IR/AffineMap.h"
#include "mlir/Dialect/SparseTensor/Transforms/Passes.h"
+#include "mlir/IR/AffineMap.h"
namespace mlir {
@@ -43,9 +43,11 @@ enum class SortMask : unsigned {
class IterationGraphSorter {
public:
/// Factory method that constructs an iteration graph sorter
- /// for the given linalg.generic operation with a specific loop ordering strategy.
- static IterationGraphSorter fromGenericOp(linalg::GenericOp genericOp,
- sparse_tensor::LoopOrderingStrategy strategy);
+ /// for the given linalg.generic operation with a specific loop ordering
+ /// strategy.
+ static IterationGraphSorter
+ fromGenericOp(linalg::GenericOp genericOp,
+ sparse_tensor::LoopOrderingStrategy strategy);
/// Returns a permutation that represents the scheduled loop order.
/// Note that the returned AffineMap could be null if the kernel
@@ -61,7 +63,8 @@ class IterationGraphSorter {
SmallVector<AffineMap> &&loop2InsLvl, Value out,
AffineMap loop2OutLvl,
SmallVector<utils::IteratorType> &&iterTypes,
- sparse_tensor::LoopOrderingStrategy strategy = sparse_tensor::LoopOrderingStrategy::kDefault);
+ sparse_tensor::LoopOrderingStrategy strategy =
+ sparse_tensor::LoopOrderingStrategy::kDefault);
// Adds all the constraints in the given loop to level map.
void addConstraints(Value t, AffineMap loop2LvlMap);
>From 57c408819f030b0f7713d330269fc1c47ffbfc6f Mon Sep 17 00:00:00 2001
From: gmalasan <145235389+gmalasan at users.noreply.github.com>
Date: Fri, 26 Sep 2025 23:35:19 -0400
Subject: [PATCH 7/7] Fix clang-format issues in SparseTensorPasses.cpp
---
.../Dialect/SparseTensor/Transforms/SparseTensorPasses.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorPasses.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorPasses.cpp
index aa31927e0602c..b660e22154688 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorPasses.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorPasses.cpp
@@ -439,9 +439,8 @@ mlir::createSparseReinterpretMapPass(ReinterpretMapScope scope) {
return std::make_unique<SparseReinterpretMap>(options);
}
-std::unique_ptr<Pass>
-mlir::createSparseReinterpretMapPass(ReinterpretMapScope scope,
- sparse_tensor::LoopOrderingStrategy strategy) {
+std::unique_ptr<Pass> mlir::createSparseReinterpretMapPass(
+ ReinterpretMapScope scope, sparse_tensor::LoopOrderingStrategy strategy) {
SparseReinterpretMapOptions options;
options.scope = scope;
options.loopOrderingStrategy = strategy;
More information about the Mlir-commits
mailing list