MLIR

Multi-Level IR Compiler Framework

'sparse_tensor' Dialect

The sparse tensor dialect is intended to hold primitives that form a bridge between high-level operations on sparse tensors and lower-level operations on the actual sparse storage schemes consisting of pointers, indices, and values. This bridge simplifies a sparse compiler pass by postponing actual code generation for the supported primitives to a later phase, either by generating calls into a runtime support library or by further lowering the primitives into actual code.

Attribute definition 

SparseTensorEncodingAttr 

An attribute to encode “TACO”-style information (see tensor-compiler.org) on sparsity properties of tensors. The encoding is eventually used by a sparse compiler pass to generate sparse code fully automatically for all tensor expressions that involve tensors with a sparse encoding. Compiler passes that run before this sparse compiler pass need to be aware of the semantics of tensor types with such an encoding.

Parameters: 

ParameterC++ typeDescription
dimLevelType::llvm::ArrayRef<SparseTensorEncodingAttr::DimLevelType>Per-dimension level type
dimOrderingAffineMap
pointerBitWidthunsigned
indexBitWidthunsigned

Operation definition 

sparse_tensor.new (::mlir::sparse_tensor::NewOp) 

Constructs a new sparse tensor

Syntax:

operation ::= `sparse_tensor.new` $source attr-dict `:` type($source) `to` type($result)

Constructs a sparse tensor value with contents taken from an opaque pointer provided by source. For targets that have access to a file system, for example, this pointer may be a filename (or file) of a sparse tensor in a particular external storage format. The form of the operation is kept deliberately very general to allow for alternative implementations in the future, such as pointers to buffers or runnable initialization code. The operation is provided as an anchor that materializes a fully typed sparse tensor values into a computation.

Example:

sparse_tensor.new %source : !Source to tensor<1024x1024xf64, #CSR>

Operands: 

OperandDescription
sourceany type

Results: 

ResultDescription
resulttensor of any type values

sparse_tensor.indices (::mlir::sparse_tensor::ToIndicesOp) 

Extract indices array at given dimension from a tensor

Syntax:

operation ::= `sparse_tensor.indices` $tensor `,` $dim attr-dict `:` type($tensor) `to` type($result)

Returns the indices array of the sparse storage scheme at the given dimension for the given sparse tensor. This is similar to the memref.buffer_cast operation in the sense that it provides a bridge between a tensor world view and a bufferized world view. Unlike the memref.buffer_cast operation, however, this sparse operation actually lowers into a call into a support library to obtain access to the indices array.

Example:

mlir 1 = sparse_tensor.indices %0, %c1 : tensor<64x64xf64, #CSR> to memref<?xindex>

Operands: 

OperandDescription
tensortensor of any type values
dimindex

Results: 

ResultDescription
resultstrided memref of any type values of rank 1

sparse_tensor.pointers (::mlir::sparse_tensor::ToPointersOp) 

Extract pointers array at given dimension from a tensor

Syntax:

operation ::= `sparse_tensor.pointers` $tensor `,` $dim attr-dict `:` type($tensor) `to` type($result)

Returns the pointers array of the sparse storage scheme at the given dimension for the given sparse tensor. This is similar to the memref.buffer_cast operation in the sense that it provides a bridge between a tensor world view and a bufferized world view. Unlike the memref.buffer_cast operation, however, this sparse operation actually lowers into a call into a support library to obtain access to the pointers array.

Example:

mlir 1 = sparse_tensor.pointers %0, %c1 : tensor<64x64xf64, #CSR> to memref<?xindex>

Operands: 

OperandDescription
tensortensor of any type values
dimindex

Results: 

ResultDescription
resultstrided memref of any type values of rank 1

sparse_tensor.tensor (::mlir::sparse_tensor::ToTensorOp) 

Reconstructs tensor from arrays(s)

Syntax:

operation ::= `sparse_tensor.tensor` $memrefs attr-dict `:` type($memrefs) `to` type($result)

Reconstructs the sparse tensor from the sparse storage scheme array(s). This is similar to the memref.load operation in the sense that it provides a bridge between a bufferized world view and a tensor world view. Unlike the memref.load operation, however, this sparse operation is used only temporarily to maintain a correctly typed intermediate representation during progressive bufferization. Eventually the operation is folded away.

The input arrays are defined unambigously by the sparsity annotations (pointers and indices for overhead storage in every compressed dimension, followed by one final values array).

Examples:

%1 = sparse_tensor.tensor %0 : memref<?xf64> to tensor<64x64xf64, #Dense>

%3 = sparse_tensor.tensor %0, %1, %2 :
   memref<?xindex>, memref<?xindex>, memref<?xf32> to tensor<10x10xf32, #CSR>

Operands: 

OperandDescription
memrefsstrided memref of any type values of rank 1

Results: 

ResultDescription
resulttensor of any type values

sparse_tensor.values (::mlir::sparse_tensor::ToValuesOp) 

Extract numerical values array from a tensor

Syntax:

operation ::= `sparse_tensor.values` $tensor attr-dict `:` type($tensor) `to` type($result)

Returns the values array of the sparse storage scheme for the given sparse tensor, independent of the actual dimension. This is similar to the memref.buffer_cast operation in the sense that it provides a bridge between a tensor world view and a bufferized world view. Unlike the memref.buffer_cast operation, however, this sparse operation actually lowers into a call into a support library to obtain access to the values array.

Example:

mlir 1 = sparse_tensor.values %0 : tensor<64x64xf64, #CSR> to memref<?xf64>

Operands: 

OperandDescription
tensortensor of any type values

Results: 

ResultDescription
resultstrided memref of any type values of rank 1