// foreach srcCoords %srcTensor
// insert translateIndicesArray(srcCoords), %tmp
// %t = sparse_tensor.cast %tmp
+ Value nnz = rewriter.create<NumberOfEntriesOp>(loc, srcTensor);
RankedTensorType cooTp = getUnorderedCOOFromType(dstTp);
- auto cooBuffer =
- rewriter.create<AllocTensorOp>(loc, cooTp, dstDynSizes).getResult();
+ Value cooBuffer =
+ rewriter
+ .create<AllocTensorOp>(loc, cooTp, dstDynSizes, Value(),
+ /*sizeHint=*/nnz, Attribute())
+ .getResult();
+
ForeachOp foreachOp = rewriter.create<ForeachOp>(
loc, srcTensor, cooBuffer,
[&](OpBuilder &builder, Location loc, ValueRange args, Value v,
SmallVector<Value> srcSizes;
sizesForTensor(rewriter, srcSizes, loc, srcTp, src);
Value tmpCoo = Value();
+ Value nnz = rewriter.create<NumberOfEntriesOp>(loc, src);
// We need a tmp COO buffer if and only if
// 1. the src tensor is not a COO and
// 2. the src tensor is not ordered in the same way as the target
getDynamicSizes(srcTp, srcSizes, dynSrcSizes);
srcTp =
getUnorderedCOOFromTypeWithOrdering(srcTp, encDst.getDimOrdering());
- tmpCoo =
- rewriter.create<AllocTensorOp>(loc, srcTp, dynSrcSizes).getResult();
+ tmpCoo = rewriter
+ .create<AllocTensorOp>(loc, srcTp, dynSrcSizes, Value(),
+ /*sizeHint=*/nnz, Attribute())
+ .getResult();
auto foreachOp = rewriter.create<ForeachOp>(
loc, src, tmpCoo,
[&](OpBuilder &builder, Location loc, ValueRange args, Value v,
// Only need to sort if the srcTp is not already sorted (we faithfully take
// the guarantee from the sparse tensor encoding).
if (!isAllDimOrdered(srcTp)) {
- // Retrieve NNZ.
- Value nnz = rewriter.create<NumberOfEntriesOp>(loc, src);
- nnz = rewriter.create<arith::IndexCastOp>(loc, rewriter.getIndexType(),
- nnz);
-
// Retrieve the values-array.
Value y = genToValues(rewriter, loc, src);
SparseTensorEncodingAttr encSrc = getSparseTensorEncoding(srcTp);
// For each element in the COO tensor, insert the element to the dst tensor.
SmallVector<Value> dynDstSizes;
getDynamicSizes(dstTp, srcSizes, dynDstSizes);
- Value dst =
- rewriter.create<AllocTensorOp>(loc, dstTp, dynDstSizes).getResult();
+ Value dst = rewriter
+ .create<AllocTensorOp>(loc, dstTp, dynDstSizes, Value(),
+ /*sizeHint=*/nnz, Attribute())
+ .getResult();
SmallVector<Value> indices(srcTp.getRank(), Value());
auto foreachOp = rewriter.create<ForeachOp>(
loc, src, dst,
// get the next element from the input file
// insert the element to %tmp
// %t = sparse_tensor.ConvertOp %tmp
- RankedTensorType cooTp =
- getUnorderedCOOFromTypeWithOrdering(dstTp, encDst.getDimOrdering());
- Value cooBuffer =
- rewriter.create<AllocTensorOp>(loc, cooTp, dynSizesArray).getResult();
-
Value c0 = constantIndex(rewriter, loc, 0);
Value c1 = constantIndex(rewriter, loc, 1);
Value nnz = createFuncCall(rewriter, loc, "getSparseTensorReaderNNZ",
{indexTp}, {reader}, EmitCInterface::Off)
.getResult(0);
- Value symmetric;
+ RankedTensorType cooTp =
+ getUnorderedCOOFromTypeWithOrdering(dstTp, encDst.getDimOrdering());
+ Value cooBuffer =
+ rewriter
+ .create<AllocTensorOp>(loc, cooTp, dynSizesArray, Value(),
+ /*sizeHint=*/nnz, Attribute())
+ .getResult();
+
// The verifier ensures only 2D tensors can have the expandSymmetry flag.
+ Value symmetric;
if (rank == 2 && op.getExpandSymmetry()) {
symmetric =
createFuncCall(rewriter, loc, "getSparseTensorReaderIsSymmetric",
// CHECK: call @copySparseTensorReaderDimSizes(%[[R]], %[[DS]])
// CHECK: %[[D0:.*]] = memref.load %[[DS]]{{\[}}%[[C0]]]
// CHECK: %[[D1:.*]] = memref.load %[[DS]]{{\[}}%[[C1]]]
-// CHECK: %[[T:.*]] = bufferization.alloc_tensor(%[[D0]], %[[D1]])
// CHECK: %[[N:.*]] = call @getSparseTensorReaderNNZ(%[[R]])
+// CHECK: %[[T:.*]] = bufferization.alloc_tensor(%[[D0]], %[[D1]]) size_hint=%[[N]]
// CHECK: %[[S:.*]] = call @getSparseTensorReaderIsSymmetric(%[[R]])
// CHECK: %[[VB:.*]] = memref.alloca()
// CHECK: %[[T2:.*]] = scf.for %{{.*}} = %[[C0]] to %[[N]] step %[[C1]] iter_args(%[[A2:.*]] = %[[T]])
// CHECK: call @copySparseTensorReaderDimSizes(%[[R]], %[[DS]])
// CHECK: %[[D0:.*]] = memref.load %[[DS]]{{\[}}%[[C0]]]
// CHECK: %[[D1:.*]] = memref.load %[[DS]]{{\[}}%[[C1]]]
-// CHECK: %[[T:.*]] = bufferization.alloc_tensor(%[[D0]], %[[D1]])
// CHECK: %[[N:.*]] = call @getSparseTensorReaderNNZ(%[[R]])
+// CHECK: %[[T:.*]] = bufferization.alloc_tensor(%[[D0]], %[[D1]]) size_hint=%[[N]]
// CHECK: %[[VB:.*]] = memref.alloca()
// CHECK: %[[T2:.*]] = scf.for %{{.*}} = %[[C0]] to %[[N]] step %[[C1]] iter_args(%[[A2:.*]] = %[[T]])
// CHECK: func.call @getSparseTensorReaderNextF32(%[[R]], %[[DS]], %[[VB]])
// CHECK: call @copySparseTensorReaderDimSizes(%[[R]], %[[DS]])
// CHECK: %[[D0:.*]] = memref.load %[[DS]]{{\[}}%[[C0]]]
// CHECK: %[[D1:.*]] = memref.load %[[DS]]{{\[}}%[[C1]]]
-// CHECK: %[[T:.*]] = bufferization.alloc_tensor(%[[D0]], %[[D1]])
// CHECK: %[[N:.*]] = call @getSparseTensorReaderNNZ(%[[R]])
+// CHECK: %[[T:.*]] = bufferization.alloc_tensor(%[[D0]], %[[D1]]) size_hint=%[[N]]
// CHECK: %[[VB:.*]] = memref.alloca()
// CHECK: %[[T2:.*]] = scf.for %{{.*}} = %[[C0]] to %[[N]] step %[[C1]] iter_args(%[[A2:.*]] = %[[T]])
// CHECK: func.call @getSparseTensorReaderNextF32(%[[R]], %[[DS]], %[[VB]])