}];
let assemblyFormat = "$source attr-dict `:` type($source) `to` type($dest)";
- let hasFolder = 1;
let hasVerifier = 1;
}
return emitError("unexpected type in convert");
}
-OpFoldResult ConvertOp::fold(ArrayRef<Attribute> operands) {
- if (getType() == getSource().getType())
- return getSource();
- return {};
-}
-
LogicalResult ToPointersOp::verify() {
auto e = getSparseTensorEncoding(getTensor().getType());
if (failed(isInBounds(getDimension().getZExtValue(), getTensor())))
}
};
+/// Sparse codegen rule for the convert operator.
+class SparseConvertConverter : public OpConversionPattern<ConvertOp> {
+public:
+ using OpConversionPattern::OpConversionPattern;
+ LogicalResult
+ matchAndRewrite(ConvertOp op, OpAdaptor adaptor,
+ ConversionPatternRewriter &rewriter) const override {
+ if (op.getType() != op.getSource().getType()) {
+ // This should be handled by rewriting before codegen.
+ return failure();
+ }
+ rewriter.replaceOp(op, adaptor.getSource());
+ return success();
+ }
+};
+
} // namespace
//===----------------------------------------------------------------------===//
SparseTensorDeallocConverter, SparseTensorLoadConverter,
SparseExpandConverter, SparseCompressConverter,
SparseInsertConverter, SparseToPointersConverter,
- SparseToIndicesConverter, SparseToValuesConverter>(
- typeConverter, patterns.getContext());
+ SparseToIndicesConverter, SparseToValuesConverter,
+ SparseConvertConverter>(typeConverter, patterns.getContext());
}
%1 = sparse_tensor.load %0 hasInserts : tensor<128xf64, #SparseVector>
return %1 : tensor<128xf64, #SparseVector>
}
+
+// CHECK-LABEL: func.func @sparse_nop_convert(
+// CHECK-SAME: %[[A0:.*]]: memref<1xindex>,
+// CHECK-SAME: %[[A1:.*]]: memref<3xindex>,
+// CHECK-SAME: %[[A2:.*]]: memref<?xi32>,
+// CHECK-SAME: %[[A3:.*]]: memref<?xi64>,
+// CHECK-SAME: %[[A4:.*]]: memref<?xf32>)
+// CHECK: return %[[A0]], %[[A1]], %[[A2]], %[[A3]], %[[A4]] : memref<1xindex>, memref<3xindex>, memref<?xi32>, memref<?xi64>, memref<?xf32>
+func.func @sparse_nop_convert(%arg0: tensor<?xf32, #SparseVector>) -> tensor<?xf32, #SparseVector> {
+ %0 = sparse_tensor.convert %arg0 : tensor<?xf32, #SparseVector> to tensor<?xf32, #SparseVector>
+ return %0 : tensor<?xf32, #SparseVector>
+}
#SparseVector = #sparse_tensor.encoding<{dimLevelType = ["compressed"]}>
-// CHECK-LABEL: func @sparse_nop_convert(
-// CHECK-SAME: %[[A:.*]]: tensor<64xf32, #sparse_tensor.encoding<{{{.*}}}>>)
-// CHECK-NOT: sparse_tensor.convert
-// CHECK: return %[[A]] : tensor<64xf32, #sparse_tensor.encoding<{{{.*}}}>>
-func.func @sparse_nop_convert(%arg0: tensor<64xf32, #SparseVector>) -> tensor<64xf32, #SparseVector> {
- %0 = sparse_tensor.convert %arg0 : tensor<64xf32, #SparseVector> to tensor<64xf32, #SparseVector>
- return %0 : tensor<64xf32, #SparseVector>
-}
-
// CHECK-LABEL: func @sparse_dce_convert(
// CHECK-SAME: %[[A:.*]]: tensor<64xf32>)
// CHECK-NOT: sparse_tensor.convert