Skip to content

Commit e8e8df4

Browse files
[mlir][sparse] Add has_runtime_library test op (#85355)
This commit adds a new test-only op: `sparse_tensor.has_runtime_library`. The op returns "1" if the sparse compiler runs in runtime library mode. This op is useful for writing test cases that require different IR depending on whether the sparse compiler runs in runtime library or codegen mode. This commit fixes a memory leak in `sparse_pack_d.mlir`. This test case uses `sparse_tensor.assemble` to create a sparse tensor SSA value from existing buffers. This runtime library reallocates+copies the existing buffers; the codegen path does not. Therefore, the test requires additional deallocations when running in runtime library mode. Alternatives considered: - Make the codegen path allocate. "Codegen" is the "default" compilation mode and it is handling `sparse_tensor.assemble` correctly. The issue is with the runtime library path, which should not allocate. Therefore, it is better to put a workaround in the runtime library path than to work around the issue with a new flag in the codegen path. - Add a `sparse_tensor.runtime_only` attribute to `bufferization.dealloc_tensor`. Verifying that the attribute can only be attached to `bufferization.dealloc_tensor` may introduce an unwanted dependency of `MLIRSparseTensorDialect` on `MLIRBufferizationDialect`.
1 parent 5124eed commit e8e8df4

File tree

4 files changed

+69
-22
lines changed

4 files changed

+69
-22
lines changed

mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorOps.td

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1419,7 +1419,7 @@ def SparseTensor_ForeachOp : SparseTensor_Op<"foreach",
14191419
}
14201420

14211421
//===----------------------------------------------------------------------===//
1422-
// Sparse Tensor Debugging Operations.
1422+
// Sparse Tensor Debugging and Test-Only Operations.
14231423
//===----------------------------------------------------------------------===//
14241424

14251425
def SparseTensor_PrintOp : SparseTensor_Op<"print">,
@@ -1440,4 +1440,15 @@ def SparseTensor_PrintOp : SparseTensor_Op<"print">,
14401440
let assemblyFormat = "$tensor attr-dict `:` type($tensor)";
14411441
}
14421442

1443+
def SparseTensor_HasRuntimeLibraryOp
1444+
: SparseTensor_Op<"has_runtime_library", []>, Results<(outs I1:$result)> {
1445+
string summary = "Indicates whether running in runtime/codegen mode";
1446+
string description = [{
1447+
Returns a boolean value that indicates whether the sparse compiler runs in
1448+
runtime library mode or not. For testing only: This op is useful for writing
1449+
test cases that require different IR depending on runtime/codegen mode.
1450+
}];
1451+
let assemblyFormat = "attr-dict";
1452+
}
1453+
14431454
#endif // SPARSETENSOR_OPS

mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,19 @@ struct SparseNewConverter : public OpConversionPattern<NewOp> {
15611561
}
15621562
};
15631563

1564+
struct SparseHasRuntimeLibraryConverter
1565+
: public OpConversionPattern<HasRuntimeLibraryOp> {
1566+
using OpConversionPattern::OpConversionPattern;
1567+
LogicalResult
1568+
matchAndRewrite(HasRuntimeLibraryOp op, OpAdaptor adaptor,
1569+
ConversionPatternRewriter &rewriter) const override {
1570+
auto i1Type = rewriter.getI1Type();
1571+
rewriter.replaceOpWithNewOp<arith::ConstantOp>(
1572+
op, i1Type, rewriter.getIntegerAttr(i1Type, 0));
1573+
return success();
1574+
}
1575+
};
1576+
15641577
} // namespace
15651578

15661579
//===----------------------------------------------------------------------===//
@@ -1572,21 +1585,21 @@ struct SparseNewConverter : public OpConversionPattern<NewOp> {
15721585
void mlir::populateSparseTensorCodegenPatterns(
15731586
TypeConverter &typeConverter, RewritePatternSet &patterns,
15741587
bool createSparseDeallocs, bool enableBufferInitialization) {
1575-
patterns.add<SparseAssembleOpConverter, SparseDisassembleOpConverter,
1576-
SparseReturnConverter, SparseCallConverter, SparseLvlOpConverter,
1577-
SparseCastConverter, SparseExtractSliceConverter,
1578-
SparseTensorLoadConverter, SparseExpandConverter,
1579-
SparseCompressConverter, SparseInsertConverter,
1580-
SparseReorderCOOConverter, SparseReMapConverter,
1581-
SparseSliceGetterOpConverter<ToSliceOffsetOp,
1582-
StorageSpecifierKind::DimOffset>,
1583-
SparseSliceGetterOpConverter<ToSliceStrideOp,
1584-
StorageSpecifierKind::DimStride>,
1585-
SparseToPositionsConverter, SparseToCoordinatesConverter,
1586-
SparseToCoordinatesBufferConverter, SparseToValuesConverter,
1587-
SparseConvertConverter, SparseNewConverter,
1588-
SparseNumberOfEntriesConverter>(typeConverter,
1589-
patterns.getContext());
1588+
patterns.add<
1589+
SparseAssembleOpConverter, SparseDisassembleOpConverter,
1590+
SparseReturnConverter, SparseCallConverter, SparseLvlOpConverter,
1591+
SparseCastConverter, SparseExtractSliceConverter,
1592+
SparseTensorLoadConverter, SparseExpandConverter, SparseCompressConverter,
1593+
SparseInsertConverter, SparseReorderCOOConverter, SparseReMapConverter,
1594+
SparseSliceGetterOpConverter<ToSliceOffsetOp,
1595+
StorageSpecifierKind::DimOffset>,
1596+
SparseSliceGetterOpConverter<ToSliceStrideOp,
1597+
StorageSpecifierKind::DimStride>,
1598+
SparseToPositionsConverter, SparseToCoordinatesConverter,
1599+
SparseToCoordinatesBufferConverter, SparseToValuesConverter,
1600+
SparseConvertConverter, SparseNewConverter,
1601+
SparseNumberOfEntriesConverter, SparseHasRuntimeLibraryConverter>(
1602+
typeConverter, patterns.getContext());
15901603
patterns.add<SparseTensorDeallocConverter>(
15911604
typeConverter, patterns.getContext(), createSparseDeallocs);
15921605
patterns.add<SparseTensorAllocConverter, SparseTensorEmptyConverter>(

mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorConversion.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,19 @@ class SparseTensorDisassembleConverter
840840
}
841841
};
842842

843+
struct SparseHasRuntimeLibraryConverter
844+
: public OpConversionPattern<HasRuntimeLibraryOp> {
845+
using OpConversionPattern::OpConversionPattern;
846+
LogicalResult
847+
matchAndRewrite(HasRuntimeLibraryOp op, OpAdaptor adaptor,
848+
ConversionPatternRewriter &rewriter) const override {
849+
auto i1Type = rewriter.getI1Type();
850+
rewriter.replaceOpWithNewOp<arith::ConstantOp>(
851+
op, i1Type, rewriter.getIntegerAttr(i1Type, 1));
852+
return success();
853+
}
854+
};
855+
843856
} // namespace
844857

845858
//===----------------------------------------------------------------------===//
@@ -868,6 +881,7 @@ void mlir::populateSparseTensorConversionPatterns(TypeConverter &typeConverter,
868881
SparseTensorToValuesConverter, SparseNumberOfEntriesConverter,
869882
SparseTensorLoadConverter, SparseTensorInsertConverter,
870883
SparseTensorExpandConverter, SparseTensorCompressConverter,
871-
SparseTensorAssembleConverter, SparseTensorDisassembleConverter>(
872-
typeConverter, patterns.getContext());
884+
SparseTensorAssembleConverter, SparseTensorDisassembleConverter,
885+
SparseHasRuntimeLibraryConverter>(typeConverter,
886+
patterns.getContext());
873887
}

mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_pack_d.mlir

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,19 @@ module {
140140
sparse_tensor.print %s1 : tensor<4x3x2xf32, #BatchedCSR>
141141
sparse_tensor.print %s2 : tensor<4x3x2xf32, #CSRDense>
142142

143-
// FIXME: doing this explicitly crashes runtime
144-
// bufferization.dealloc_tensor %s0 : tensor<4x3x2xf32, #CCC>
145-
// bufferization.dealloc_tensor %s1 : tensor<4x3x2xf32, #BatchedCSR>
146-
// bufferization.dealloc_tensor %s2 : tensor<4x3x2xf32, #CSRDense>
143+
// TODO: This check is no longer needed once the codegen path uses the
144+
// buffer deallocation pass. "dealloc_tensor" turn into a no-op in the
145+
// codegen path.
146+
%has_runtime = sparse_tensor.has_runtime_library
147+
scf.if %has_runtime {
148+
// sparse_tensor.assemble copies buffers when running with the runtime
149+
// library. Deallocations are needed not needed when running in codgen
150+
// mode.
151+
bufferization.dealloc_tensor %s0 : tensor<4x3x2xf32, #CCC>
152+
bufferization.dealloc_tensor %s1 : tensor<4x3x2xf32, #BatchedCSR>
153+
bufferization.dealloc_tensor %s2 : tensor<4x3x2xf32, #CSRDense>
154+
}
155+
147156
return
148157
}
149158
}

0 commit comments

Comments
 (0)