25#define GEN_PASS_DEF_SPARSEASSEMBLER
26#define GEN_PASS_DEF_SPARSEREINTERPRETMAP
27#define GEN_PASS_DEF_PRESPARSIFICATIONREWRITE
28#define GEN_PASS_DEF_SPARSIFICATIONPASS
29#define GEN_PASS_DEF_LOWERSPARSEITERATIONTOSCF
30#define GEN_PASS_DEF_LOWERSPARSEOPSTOFOREACH
31#define GEN_PASS_DEF_LOWERFOREACHTOSCF
32#define GEN_PASS_DEF_SPARSETENSORCONVERSIONPASS
33#define GEN_PASS_DEF_SPARSETENSORCODEGEN
34#define GEN_PASS_DEF_SPARSEBUFFERREWRITE
35#define GEN_PASS_DEF_SPARSEVECTORIZATION
36#define GEN_PASS_DEF_SPARSEGPUCODEGEN
37#define GEN_PASS_DEF_STAGESPARSEOPERATIONS
38#define GEN_PASS_DEF_STORAGESPECIFIERTOLLVM
39#include "mlir/Dialect/SparseTensor/Transforms/Passes.h.inc"
51static bool supportsCollapsedRangeBetween(
LevelType lt) {
55static LogicalResult verifyLowerableCollapsedIterSpaces(
Operation *op) {
57 auto [lvlLo, lvlHi] = op.getLvlRange();
58 SparseTensorEncodingAttr enc = cast<SparseTensorEncodingAttr>(
60 for (
Level lvl = lvlLo + 1; lvl < lvlHi; ++lvl) {
62 if (!supportsCollapsedRangeBetween(lt)) {
63 op.
emitOpError() <<
"cannot lower collapsed iteration space with "
70 return failure(
result.wasInterrupted());
74 SparseAssembler() =
default;
75 SparseAssembler(
const SparseAssembler &pass) =
default;
76 SparseAssembler(
bool dO) { directOut = dO; }
78 void runOnOperation()
override {
86struct SparseReinterpretMap
88 SparseReinterpretMap() =
default;
89 SparseReinterpretMap(
const SparseReinterpretMap &pass) =
default;
90 SparseReinterpretMap(
const SparseReinterpretMapOptions &
options) {
92 loopOrderingStrategy =
options.loopOrderingStrategy;
95 void runOnOperation()
override {
97 RewritePatternSet patterns(ctx);
103struct PreSparsificationRewritePass
105 PreSparsificationRewritePass() =
default;
106 PreSparsificationRewritePass(
const PreSparsificationRewritePass &pass) =
117struct SparsificationPass
119 SparsificationPass() =
default;
120 SparsificationPass(
const SparsificationPass &pass) =
default;
122 parallelization =
options.parallelizationStrategy;
123 sparseEmitStrategy =
options.sparseEmitStrategy;
124 enableRuntimeLibrary =
options.enableRuntimeLibrary;
127 void runOnOperation()
override {
131 enableRuntimeLibrary);
135 scf::ForOp::getCanonicalizationPatterns(patterns, ctx);
140struct StageSparseOperationsPass
142 StageSparseOperationsPass() =
default;
143 StageSparseOperationsPass(
const StageSparseOperationsPass &pass) =
default;
144 void runOnOperation()
override {
152struct LowerSparseOpsToForeachPass
154 LowerSparseOpsToForeachPass() =
default;
155 LowerSparseOpsToForeachPass(
const LowerSparseOpsToForeachPass &pass) =
157 LowerSparseOpsToForeachPass(
bool enableRT,
bool convert) {
158 enableRuntimeLibrary = enableRT;
159 enableConvert = convert;
162 void runOnOperation()
override {
164 RewritePatternSet patterns(ctx);
171struct LowerForeachToSCFPass
173 LowerForeachToSCFPass() =
default;
174 LowerForeachToSCFPass(
const LowerForeachToSCFPass &pass) =
default;
184struct LowerSparseIterationToSCFPass
186 LowerSparseIterationToSCFPass> {
187 LowerSparseIterationToSCFPass() =
default;
188 LowerSparseIterationToSCFPass(
const LowerSparseIterationToSCFPass &) =
192 if (failed(verifyLowerableCollapsedIterSpaces(
getOperation()))) {
203 target.addLegalDialect<arith::ArithDialect, linalg::LinalgDialect,
204 memref::MemRefDialect, scf::SCFDialect,
205 sparse_tensor::SparseTensorDialect>();
206 target.addIllegalOp<CoIterateOp, ExtractIterSpaceOp, ExtractValOp,
208 target.addLegalOp<UnrealizedConversionCastOp>();
212 std::move(patterns))))
217struct SparseTensorConversionPass
219 SparseTensorConversionPass() =
default;
220 SparseTensorConversionPass(
const SparseTensorConversionPass &pass) =
default;
228 target.addIllegalDialect<SparseTensorDialect>();
232 target.addDynamicallyLegalOp<func::FuncOp>([&](func::FuncOp op) {
233 return converter.isSignatureLegal(op.getFunctionType());
235 target.addDynamicallyLegalOp<func::CallOp>([&](func::CallOp op) {
236 return converter.isSignatureLegal(op.getCalleeType());
238 target.addDynamicallyLegalOp<func::ReturnOp>([&](func::ReturnOp op) {
241 target.addDynamicallyLegalOp<tensor::DimOp>([&](tensor::DimOp op) {
244 target.addDynamicallyLegalOp<tensor::CastOp>([&](tensor::CastOp op) {
245 return converter.isLegal(op.getSource().getType()) &&
246 converter.isLegal(op.getDest().getType());
248 target.addDynamicallyLegalOp<tensor::ExpandShapeOp>(
249 [&](tensor::ExpandShapeOp op) {
250 return converter.isLegal(op.getSrc().getType()) &&
253 target.addDynamicallyLegalOp<tensor::CollapseShapeOp>(
254 [&](tensor::CollapseShapeOp op) {
255 return converter.isLegal(op.getSrc().getType()) &&
258 target.addDynamicallyLegalOp<bufferization::AllocTensorOp>(
259 [&](bufferization::AllocTensorOp op) {
260 return converter.isLegal(op.getType());
262 target.addDynamicallyLegalOp<bufferization::DeallocTensorOp>(
263 [&](bufferization::DeallocTensorOp op) {
264 return converter.isLegal(op.getTensor().getType());
268 target.addLegalOp<complex::ConstantOp, complex::NotEqualOp, linalg::FillOp,
269 linalg::YieldOp, tensor::ExtractOp,
270 tensor::FromElementsOp>();
272 arith::ArithDialect, bufferization::BufferizationDialect,
273 LLVM::LLVMDialect, memref::MemRefDialect, scf::SCFDialect>();
276 populateFunctionOpInterfaceTypeConversionPattern<func::FuncOp>(patterns,
283 std::move(patterns))))
288struct SparseTensorCodegenPass
290 SparseTensorCodegenPass() =
default;
291 SparseTensorCodegenPass(
const SparseTensorCodegenPass &pass) =
default;
292 SparseTensorCodegenPass(
bool createDeallocs,
bool enableInit) {
293 createSparseDeallocs = createDeallocs;
294 enableBufferInitialization = enableInit;
297 void runOnOperation()
override {
303 target.addIllegalDialect<SparseTensorDialect>();
304 target.addLegalOp<SortOp>();
305 target.addLegalOp<PushBackOp>();
307 target.addLegalOp<GetStorageSpecifierOp>();
308 target.addLegalOp<SetStorageSpecifierOp>();
309 target.addLegalOp<StorageSpecifierInitOp>();
311 target.addLegalOp<tensor::FromElementsOp>();
316 target.addDynamicallyLegalOp<func::FuncOp>([&](func::FuncOp op) {
317 return converter.isSignatureLegal(op.getFunctionType());
319 target.addDynamicallyLegalOp<func::CallOp>([&](func::CallOp op) {
320 return converter.isSignatureLegal(op.getCalleeType());
322 target.addDynamicallyLegalOp<func::ReturnOp>([&](func::ReturnOp op) {
325 target.addDynamicallyLegalOp<bufferization::AllocTensorOp>(
326 [&](bufferization::AllocTensorOp op) {
327 return converter.isLegal(op.getType());
329 target.addDynamicallyLegalOp<bufferization::DeallocTensorOp>(
330 [&](bufferization::DeallocTensorOp op) {
331 return converter.isLegal(op.getTensor().getType());
335 target.addLegalOp<linalg::FillOp, linalg::YieldOp>();
337 arith::ArithDialect, bufferization::BufferizationDialect,
338 complex::ComplexDialect, memref::MemRefDialect, scf::SCFDialect>();
339 target.addLegalOp<UnrealizedConversionCastOp>();
341 populateFunctionOpInterfaceTypeConversionPattern<func::FuncOp>(patterns,
346 converter, patterns, createSparseDeallocs, enableBufferInitialization);
348 std::move(patterns))))
353struct SparseBufferRewritePass
355 SparseBufferRewritePass() =
default;
356 SparseBufferRewritePass(
const SparseBufferRewritePass &pass) =
default;
357 SparseBufferRewritePass(
bool enableInit) {
358 enableBufferInitialization = enableInit;
369struct SparseVectorizationPass
371 SparseVectorizationPass() =
default;
372 SparseVectorizationPass(
const SparseVectorizationPass &pass) =
default;
373 SparseVectorizationPass(
unsigned vl,
bool vla,
bool sidx32) {
375 enableVLAVectorization = vla;
376 enableSIMDIndex32 = sidx32;
379 void runOnOperation()
override {
380 if (vectorLength == 0)
385 patterns, vectorLength, enableVLAVectorization, enableSIMDIndex32);
391struct SparseGPUCodegenPass
393 SparseGPUCodegenPass() =
default;
394 SparseGPUCodegenPass(
const SparseGPUCodegenPass &pass) =
default;
395 SparseGPUCodegenPass(
unsigned nT,
bool enableRT) {
397 enableRuntimeLibrary = enableRT;
400 void runOnOperation()
override {
411struct StorageSpecifierToLLVMPass
413 StorageSpecifierToLLVMPass() =
default;
422 target.addIllegalDialect<SparseTensorDialect>();
423 target.addDynamicallyLegalOp<func::FuncOp>([&](func::FuncOp op) {
424 return converter.isSignatureLegal(op.getFunctionType());
426 target.addDynamicallyLegalOp<func::CallOp>([&](func::CallOp op) {
427 return converter.isSignatureLegal(op.getCalleeType());
429 target.addDynamicallyLegalOp<func::ReturnOp>([&](func::ReturnOp op) {
432 target.addLegalDialect<arith::ArithDialect, LLVM::LLVMDialect>();
434 populateFunctionOpInterfaceTypeConversionPattern<func::FuncOp>(patterns,
443 std::move(patterns))))
455 return std::make_unique<SparseAssembler>();
459 return std::make_unique<SparseReinterpretMap>();
466 return std::make_unique<SparseReinterpretMap>(
options);
473 options.loopOrderingStrategy = strategy;
474 return std::make_unique<SparseReinterpretMap>(
options);
478 return std::make_unique<PreSparsificationRewritePass>();
482 return std::make_unique<SparsificationPass>();
487 return std::make_unique<SparsificationPass>(
options);
491 return std::make_unique<StageSparseOperationsPass>();
495 return std::make_unique<LowerSparseOpsToForeachPass>();
500 return std::make_unique<LowerSparseOpsToForeachPass>(enableRT, enableConvert);
504 return std::make_unique<LowerForeachToSCFPass>();
508 return std::make_unique<LowerSparseIterationToSCFPass>();
512 return std::make_unique<SparseTensorConversionPass>();
516 return std::make_unique<SparseTensorCodegenPass>();
521 bool enableBufferInitialization) {
522 return std::make_unique<SparseTensorCodegenPass>(createSparseDeallocs,
523 enableBufferInitialization);
527 return std::make_unique<SparseBufferRewritePass>();
532 return std::make_unique<SparseBufferRewritePass>(enableBufferInitialization);
536 return std::make_unique<SparseVectorizationPass>();
541 bool enableVLAVectorization,
542 bool enableSIMDIndex32) {
543 return std::make_unique<SparseVectorizationPass>(
544 vectorLength, enableVLAVectorization, enableSIMDIndex32);
548 return std::make_unique<SparseGPUCodegenPass>();
553 return std::make_unique<SparseGPUCodegenPass>(numThreads, enableRT);
557 return std::make_unique<StorageSpecifierToLLVMPass>();
static llvm::ManagedStatic< PassManagerOptions > options
func::FuncOp getOperation()
Operation is the basic unit of execution within MLIR.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
operand_type_range getOperandTypes()
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT > walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one),...
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
virtual void runOnOperation()=0
The polymorphic API that runs the pass over the currently held operation.
void signalPassFailure()
Signal that some invariant was broken when running.
Sparse tensor type converter into an actual buffer.
Sparse tensor type converter into an opaque pointer.
Type getType() const
Return the type of this value.
A utility result that is used to signal how to proceed with an ongoing walk:
static WalkResult advance()
static WalkResult interrupt()
::mlir::Pass::Option< mlir::ReinterpretMapScope > scope
void populateSCFStructuralTypeConversionsAndLegality(const TypeConverter &typeConverter, RewritePatternSet &patterns, ConversionTarget &target, PatternBenefit benefit=1)
Populates patterns for SCF structural type conversions and sets up the provided ConversionTarget with...
std::string toMLIRString(LevelType lt)
bool isSingletonLT(LevelType lt)
RankedTensorType getRankedTensorType(T &&t)
Convenience method to abbreviate casting getType().
uint64_t Level
The type of level identifiers and level-ranks.
LoopOrderingStrategy
Defines a strategy for loop ordering during sparse code generation.
void populateVectorToVectorCanonicalizationPatterns(RewritePatternSet &patterns, PatternBenefit benefit=1)
Collect a set of vector-to-vector canonicalization patterns.
Include the generated interface declarations.
std::unique_ptr< Pass > createSparseVectorizationPass()
std::unique_ptr< Pass > createSparseAssembler()
void populateStorageSpecifierToLLVMPatterns(const TypeConverter &converter, RewritePatternSet &patterns)
std::unique_ptr< Pass > createLowerSparseOpsToForeachPass()
std::unique_ptr< Pass > createSparseTensorCodegenPass()
void populateReturnOpTypeConversionPattern(RewritePatternSet &patterns, const TypeConverter &converter, PatternBenefit benefit=1)
Add a pattern to the given pattern list to rewrite return ops to use operands that have been legalize...
void populateSparseTensorCodegenPatterns(const TypeConverter &typeConverter, RewritePatternSet &patterns, bool createSparseDeallocs, bool enableBufferInitialization)
Sets up sparse tensor codegen rules.
std::unique_ptr< Pass > createSparseGPUCodegenPass()
std::unique_ptr< Pass > createSparseReinterpretMapPass()
LogicalResult applyPatternsGreedily(Region ®ion, const FrozenRewritePatternSet &patterns, GreedyRewriteConfig config=GreedyRewriteConfig(), bool *changed=nullptr)
Rewrite ops in the given region, which must be isolated from above, by repeatedly applying the highes...
void populateSparseGPULibgenPatterns(RewritePatternSet &patterns, bool enableRT)
void populateCallOpTypeConversionPattern(RewritePatternSet &patterns, const TypeConverter &converter, PatternBenefit benefit=1)
Add a pattern to the given pattern list to convert the operand and result types of a CallOp with the ...
std::unique_ptr< Pass > createSparseTensorConversionPass()
std::unique_ptr< Pass > createSparseBufferRewritePass()
void populateSparseTensorConversionPatterns(const TypeConverter &typeConverter, RewritePatternSet &patterns)
Sets up sparse tensor conversion rules.
void populateSparseBufferRewriting(RewritePatternSet &patterns, bool enableBufferInitialization)
void populatePreSparsificationRewriting(RewritePatternSet &patterns)
void populateBranchOpInterfaceTypeConversionPattern(RewritePatternSet &patterns, const TypeConverter &converter, function_ref< bool(BranchOpInterface branchOp, int idx)> shouldConvertBranchOperand=nullptr, PatternBenefit benefit=1)
Add a pattern to the given pattern list to rewrite branch operations to use operands that have been l...
void populateSparseVectorizationPatterns(RewritePatternSet &patterns, unsigned vectorLength, bool enableVLAVectorization, bool enableSIMDIndex32)
Populates the given patterns list with vectorization rules.
ReinterpretMapScope
Defines a scope for reinterpret map pass.
void populateSparsificationPatterns(RewritePatternSet &patterns, const SparsificationOptions &options=SparsificationOptions())
Sets up sparsification rewriting rules with the given options.
void populateLowerSparseIterationToSCFPatterns(const TypeConverter &converter, RewritePatternSet &patterns)
void populateLowerSparseOpsToForeachPatterns(RewritePatternSet &patterns, bool enableRT, bool enableConvert)
std::unique_ptr< Pass > createStorageSpecifierToLLVMPass()
std::unique_ptr< Pass > createPreSparsificationRewritePass()
std::unique_ptr< Pass > createLowerForeachToSCFPass()
void populateSparseAssembler(RewritePatternSet &patterns, bool directOut)
void populateStageSparseOperationsPatterns(RewritePatternSet &patterns)
Sets up StageSparseOperation rewriting rules.
std::unique_ptr< Pass > createLowerSparseIterationToSCFPass()
void populateSparseGPUCodegenPatterns(RewritePatternSet &patterns, unsigned numThreads)
std::unique_ptr< Pass > createStageSparseOperationsPass()
std::unique_ptr< Pass > createSparsificationPass()
void populateSparseReinterpretMap(RewritePatternSet &patterns, ReinterpretMapScope scope, sparse_tensor::LoopOrderingStrategy strategy=sparse_tensor::LoopOrderingStrategy::kDefault)
void populateLowerForeachToSCFPatterns(RewritePatternSet &patterns)
Type converter for iter_space and iterator.
Options for the Sparsification pass.
This enum defines all the sparse representations supportable by the SparseTensor dialect.