MLIR  20.0.0git
SparseTensor.h
Go to the documentation of this file.
1 //===- SparseTensor.h - Sparse tensor dialect -------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef MLIR_DIALECT_SPARSETENSOR_IR_SPARSETENSOR_H_
10 #define MLIR_DIALECT_SPARSETENSOR_IR_SPARSETENSOR_H_
11 
15 #include "mlir/IR/BuiltinTypes.h"
16 #include "mlir/IR/Dialect.h"
17 #include "mlir/IR/OpDefinition.h"
19 #include "mlir/IR/TensorEncoding.h"
24 
25 #include "llvm/ADT/bit.h"
26 
27 //===----------------------------------------------------------------------===//
28 //
29 // Type aliases to help code be more self-documenting. Unfortunately
30 // these are not type-checked, so they only provide documentation rather
31 // than doing anything to prevent mixups.
32 //
33 //===----------------------------------------------------------------------===//
34 
35 namespace mlir {
36 namespace sparse_tensor {
37 
38 /// The type of dimension identifiers and dimension-ranks.
39 using Dimension = uint64_t;
40 
41 /// The type of level identifiers and level-ranks.
42 using Level = uint64_t;
43 
44 /// The type for individual components of a compile-time shape,
45 /// including the value `ShapedType::kDynamic` (for shapes).
46 using Size = int64_t;
47 
48 /// A simple structure that encodes a range of levels in the sparse tensors
49 /// that forms a COO segment.
50 struct COOSegment {
51  std::pair<Level, Level> lvlRange; // [low, high)
52  bool isSoA;
53 
54  bool isAoS() const { return !isSoA; }
55  bool isSegmentStart(Level l) const { return l == lvlRange.first; }
56  bool inSegment(Level l) const {
57  return l >= lvlRange.first && l < lvlRange.second;
58  }
59 };
60 
61 /// A simple wrapper to encode a bitset of (at most 64) levels, currently used
62 /// by `sparse_tensor.iterate` operation for the set of levels on which the
63 /// coordinates should be loaded.
64 class LevelSet {
65  uint64_t bits = 0;
66 
67 public:
68  LevelSet() = default;
69  explicit LevelSet(uint64_t bits) : bits(bits) {}
70  operator uint64_t() const { return bits; }
71 
72  LevelSet &set(unsigned i) {
73  assert(i < 64);
74  bits |= static_cast<uint64_t>(0x01u) << i;
75  return *this;
76  }
77 
79  bits |= static_cast<uint64_t>(lhs);
80  return *this;
81  }
82 
83  LevelSet &lshift(unsigned offset) {
84  bits = bits << offset;
85  return *this;
86  }
87 
88  bool operator[](unsigned i) const {
89  assert(i < 64);
90  return (bits & (1 << i)) != 0;
91  }
92  unsigned max() const { return 64 - llvm::countl_zero(bits); }
93  unsigned count() const { return llvm::popcount(bits); }
94  bool empty() const { return bits == 0; }
95 };
96 
97 } // namespace sparse_tensor
98 } // namespace mlir
99 
100 //===----------------------------------------------------------------------===//
101 // TableGen-defined classes
102 //===----------------------------------------------------------------------===//
103 
104 #define GET_ATTRDEF_CLASSES
105 #include "mlir/Dialect/SparseTensor/IR/SparseTensorAttrEnums.h.inc"
106 
107 #define GET_ATTRDEF_CLASSES
108 #include "mlir/Dialect/SparseTensor/IR/SparseTensorAttrDefs.h.inc"
109 
110 #define GET_TYPEDEF_CLASSES
111 #include "mlir/Dialect/SparseTensor/IR/SparseTensorTypes.h.inc"
112 
113 #define GET_OP_CLASSES
114 #include "mlir/Dialect/SparseTensor/IR/SparseTensorOps.h.inc"
115 
116 #include "mlir/Dialect/SparseTensor/IR/SparseTensorOpsDialect.h.inc"
117 
118 //===----------------------------------------------------------------------===//
119 // Additional convenience methods.
120 //===----------------------------------------------------------------------===//
121 
122 namespace mlir {
123 namespace sparse_tensor {
124 
125 /// Convenience method to abbreviate casting `getType()`.
126 template <typename T>
127 inline RankedTensorType getRankedTensorType(T &&t) {
128  assert(static_cast<bool>(std::forward<T>(t)) &&
129  "getRankedTensorType got null argument");
130  return dyn_cast<RankedTensorType>(std::forward<T>(t).getType());
131 }
132 
133 /// Convenience method to abbreviate casting `getType()`.
134 template <typename T>
135 inline MemRefType getMemRefType(T &&t) {
136  assert(static_cast<bool>(std::forward<T>(t)) &&
137  "getMemRefType got null argument");
138  return cast<MemRefType>(std::forward<T>(t).getType());
139 }
140 
141 /// Convenience method to get a sparse encoding attribute from a type.
142 /// Returns null-attribute for any type without an encoding.
143 SparseTensorEncodingAttr getSparseTensorEncoding(Type type);
144 
145 /// Returns true iff the type range has any sparse tensor type.
146 inline bool hasAnySparseType(TypeRange types) {
147  return llvm::any_of(types, [](Type type) {
148  return getSparseTensorEncoding(type) != nullptr;
149  });
150 }
151 
152 /// Returns true iff MLIR operand has any sparse operand.
153 inline bool hasAnySparseOperand(Operation *op) {
154  return hasAnySparseType(op->getOperands().getTypes());
155 }
156 
157 /// Returns true iff MLIR operand has any sparse result.
158 inline bool hasAnySparseResult(Operation *op) {
159  return hasAnySparseType(op->getResults().getTypes());
160 }
161 
162 /// Returns true iff MLIR operand has any sparse operand or result.
164  return hasAnySparseOperand(op) || hasAnySparseResult(op);
165 }
166 
167 /// Returns true iff MLIR operation has any sparse tensor with non-identity
168 /// dim2lvl maps.
170 
171 //
172 // Inference.
173 //
174 
175 /// Given the dimToLvl map, infers the lvlToDim map, or returns
176 /// empty Affine map when inference fails.
177 AffineMap inferLvlToDim(AffineMap dimToLvl, MLIRContext *context);
178 
179 /// Returns the lvlToDim map for the given dimToLvl map specific
180 /// to the block sparse cases.
181 /// Asserts on failure (so only use when known to succeed).
183 
184 /// Given the dimToLvl map, returns the block sizes in a vector.
185 /// For instance, a 2x3 block will return [2, 3]. Unblocked dimension i
186 /// will return 0, and i floordiv 1, i mod 1 will return 1. Therefore,
187 /// the example below will return [0, 1].
188 /// map = ( i, j ) ->
189 /// ( i : dense,
190 /// j floordiv 1 : compressed,
191 /// j mod 1 : dense
192 /// )
193 /// Only valid block sparsity will be accepted.
195 
196 /// Given the dimToLvl map, returns if it's block sparsity.
197 bool isBlockSparsity(AffineMap dimToLvl);
198 
199 //
200 // Reordering.
201 //
202 
203 /// Convenience method to translate the given level to the corresponding
204 /// dimension.
205 /// Requires: `enc` has a permuted dim2lvl map and `0 <= l < lvlRank`.
206 Dimension toDim(SparseTensorEncodingAttr enc, Level l);
207 
208 /// Convenience method to translate the given dimension to the corresponding
209 /// level.
210 /// Requires: `enc` has a permuted dim2lvl map and `0 <= d < dimRank`.
211 Level toLvl(SparseTensorEncodingAttr enc, Dimension d);
212 
213 } // namespace sparse_tensor
214 } // namespace mlir
215 
216 #endif // MLIR_DIALECT_SPARSETENSOR_IR_SPARSETENSOR_H_
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
Definition: AffineMap.h:46
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
This class provides an abstraction over the various different ranges of value types.
Definition: TypeRange.h:36
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
A simple wrapper to encode a bitset of (at most 64) levels, currently used by sparse_tensor....
Definition: SparseTensor.h:64
bool operator[](unsigned i) const
Definition: SparseTensor.h:88
LevelSet & lshift(unsigned offset)
Definition: SparseTensor.h:83
LevelSet & operator|=(LevelSet lhs)
Definition: SparseTensor.h:78
LevelSet & set(unsigned i)
Definition: SparseTensor.h:72
bool hasAnySparseOperandOrResult(Operation *op)
Returns true iff MLIR operand has any sparse operand or result.
Definition: SparseTensor.h:163
Dimension toDim(SparseTensorEncodingAttr enc, Level l)
Convenience method to translate the given level to the corresponding dimension.
uint64_t Dimension
The type of dimension identifiers and dimension-ranks.
Definition: SparseTensor.h:39
uint64_t Level
The type of level identifiers and level-ranks.
Definition: SparseTensor.h:42
int64_t Size
The type for individual components of a compile-time shape, including the value ShapedType::kDynamic ...
Definition: SparseTensor.h:46
RankedTensorType getRankedTensorType(T &&t)
Convenience method to abbreviate casting getType().
Definition: SparseTensor.h:127
AffineMap inferLvlToDim(AffineMap dimToLvl, MLIRContext *context)
Given the dimToLvl map, infers the lvlToDim map, or returns empty Affine map when inference fails.
SparseTensorEncodingAttr getSparseTensorEncoding(Type type)
Convenience method to get a sparse encoding attribute from a type.
MemRefType getMemRefType(T &&t)
Convenience method to abbreviate casting getType().
Definition: SparseTensor.h:135
bool hasAnySparseType(TypeRange types)
Returns true iff the type range has any sparse tensor type.
Definition: SparseTensor.h:146
Level toLvl(SparseTensorEncodingAttr enc, Dimension d)
Convenience method to translate the given dimension to the corresponding level.
bool isBlockSparsity(AffineMap dimToLvl)
Given the dimToLvl map, returns if it's block sparsity.
bool hasAnyNonIdentityOperandsOrResults(Operation *op)
Returns true iff MLIR operation has any sparse tensor with non-identity dim2lvl maps.
bool hasAnySparseResult(Operation *op)
Returns true iff MLIR operand has any sparse result.
Definition: SparseTensor.h:158
bool hasAnySparseOperand(Operation *op)
Returns true iff MLIR operand has any sparse operand.
Definition: SparseTensor.h:153
SmallVector< unsigned > getBlockSize(AffineMap dimToLvl)
Given the dimToLvl map, returns the block sizes in a vector.
AffineMap inverseBlockSparsity(AffineMap dimToLvl, MLIRContext *context)
Returns the lvlToDim map for the given dimToLvl map specific to the block sparse cases.
Include the generated interface declarations.
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
Definition: Utils.cpp:305
A simple structure that encodes a range of levels in the sparse tensors that forms a COO segment.
Definition: SparseTensor.h:50
bool inSegment(Level l) const
Definition: SparseTensor.h:56
bool isSegmentStart(Level l) const
Definition: SparseTensor.h:55
std::pair< Level, Level > lvlRange
Definition: SparseTensor.h:51