MLIR  20.0.0git
CodegenEnv.h
Go to the documentation of this file.
1 //===- CodegenEnv.h - Code generation environment class ---------*- 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 // This header file defines the code generation environment class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_DIALECT_SPARSETENSOR_TRANSFORMS_UTILS_CODEGENENV_H_
14 #define MLIR_DIALECT_SPARSETENSOR_TRANSFORMS_UTILS_CODEGENENV_H_
15 
16 #include "CodegenUtils.h"
17 #include "LoopEmitter.h"
18 
23 #include <optional>
24 
25 namespace mlir {
26 namespace sparse_tensor {
27 
28 /// The code generation environment class aggregates a number of data
29 /// structures that are needed during the code generation phase of
30 /// sparsification. This environment simplifies passing around such
31 /// data during sparsification (rather than passing around all the
32 /// individual compoments where needed). Furthermore, it provides
33 /// convience methods that keep implementation details transparent
34 /// to sparsification while asserting on internal consistency.
35 class CodegenEnv {
36 public:
37  /// Constructs a code generation environment which can be
38  /// passed around during sparsification for bookkeeping
39  /// together with some consistency asserts.
40  CodegenEnv(linalg::GenericOp linop, SparsificationOptions opts,
41  unsigned numTensors, unsigned numLoops, unsigned maxRank);
42 
43  //
44  // General methods.
45  //
46 
47  LogicalResult initTensorExp();
48  ExprId getExprId() const { return tensorExp; }
49 
50  linalg::GenericOp op() const { return linalgOp; }
51  const SparsificationOptions &options() const { return sparseOptions; }
52  bool generatingSparseIterator() const {
53  return sparseOptions.sparseEmitStrategy ==
55  }
56  Merger &merger() { return latticeMerger; }
57  LoopEmitter &emitter() { return loopEmitter; }
58 
59  void startEmit(SparseEmitStrategy emitStrategy);
60 
61  /// Generates loop boundary statements (entering/exiting loops). The function
62  /// passes and updates the passed-in parameters.
63  std::optional<Operation *>
65  std::optional<Operation *>(MutableArrayRef<Value> parameters)>
66  callback);
67 
68  //
69  // Merger delegates.
70  //
71 
72  constexpr TensorId makeTensorId(unsigned t) const {
73  return latticeMerger.makeTensorId(t);
74  }
75  constexpr LoopId makeLoopId(unsigned i) const {
76  return latticeMerger.makeLoopId(i);
77  }
78  constexpr TensorLoopId makeTensorLoopId(unsigned t, unsigned i) const {
79  return latticeMerger.makeTensorLoopId(t, i);
80  }
81  const TensorExp &exp(ExprId e) const { return latticeMerger.exp(e); }
82  const LatPoint &lat(LatPointId l) const { return latticeMerger.lat(l); }
83  ArrayRef<LatPointId> set(LatSetId s) const { return latticeMerger.set(s); }
84  LevelType lt(TensorId t, LoopId i) const {
85  return latticeMerger.getLvlType(t, i);
86  }
87  LevelType lt(TensorLoopId b) const { return latticeMerger.getLvlType(b); }
88 
89  unsigned getLoopNum() const { return latticeMerger.getNumLoops(); }
90 
91  //
92  // LoopEmitter delegates.
93  //
94 
96  // Make sure LoopEmitter, GenericOp, and Merger agree on the number of
97  // tensors.
98  assert(loopEmitter.getNumManifestTensors() == linalgOp->getNumOperands() &&
99  loopEmitter.getNumTensors() == latticeMerger.getNumTensors() &&
100  loopEmitter.getOutTensorId() == latticeMerger.getOutTensorID() &&
101  loopEmitter.getSynTensorId() == latticeMerger.getSynTensorID());
102  return loopEmitter.makeTensorLevel(t, l);
103  }
104  TensorLevel makeTensorLevel(std::pair<TensorId, Level> tlPair) const {
105  return makeTensorLevel(tlPair.first, tlPair.second);
106  }
107  std::pair<TensorId, Level> unpackTensorLevel(TensorLevel tl) const {
108  return loopEmitter.unpackTensorLevel(tl);
109  }
110  template <class ContainerTy>
111  auto unpackTensorLevelRange(ContainerTy &&c) const {
112  return loopEmitter.unpackTensorLevelRange(std::forward<ContainerTy>(c));
113  }
114 
115  unsigned getCurrentDepth() const { return loopEmitter.getCurrentDepth(); }
116 
117  //
118  // Code generation environment verify functions.
119  //
120 
121  /// Whether the tensor expression is admissible for codegen.
122  /// It also sets the sparseOut if the output tensor is sparse.
124 
125  /// Returns the induction-variable for the given loop.
126  Value getLoopVar(LoopId i) const;
127 
128  //
129  // Sparse tensor output and expansion methods.
130  //
131 
132  bool hasSparseOutput() const { return sparseOut != nullptr; }
133  bool isSparseOutput(OpOperand *o) const { return sparseOut == o; }
134 
135  Value getInsertionChain() const { return insChain; }
136  void updateInsertionChain(Value chain);
137 
138  bool atExpandLevel(OpOperand *o, unsigned rank, LoopId n) const;
139  void startExpand(Value values, Value filled, Value added, Value count);
140  bool isExpand() const { return expValues != nullptr; }
141  void updateExpandCount(Value count);
142  Value getExpandValues() const { return expValues; }
143  Value getExpandFilled() const { return expFilled; }
144  Value getExpandAdded() const { return expAdded; }
145  Value getExpandCount() const { return expCount; }
146  void endExpand();
147 
148  //
149  // Reduction methods.
150  //
151 
152  void startReduc(ExprId exp, Value val);
153  bool isReduc() const { return redExp != detail::kInvalidId; }
154  void updateReduc(Value val);
155  Value getReduc() const { return redVal; }
156  Value endReduc();
157 
158  void startValidLexInsert(Value val);
159  bool isValidLexInsert() const { return redValidLexInsert != nullptr; }
160  void updateValidLexInsert(Value val);
161  Value getValidLexInsert() const { return redValidLexInsert; }
162  void endValidLexInsert();
163 
165  bool isCustomReduc() const { return redCustom != detail::kInvalidId; }
166  Value getCustomRedId() const;
167  void endCustomReduc();
168 
169 private:
170  // Linalg operation.
171  linalg::GenericOp linalgOp;
172 
173  // Sparsification options.
174  SparsificationOptions sparseOptions;
175 
176  // Merger helper class.
177  Merger latticeMerger;
178 
179  // Loop emitter helper class.
180  LoopEmitter loopEmitter;
181 
182  // Sparse tensor as output. Implemented either through direct injective
183  // insertion in lexicographic index order or through access pattern
184  // expansion in the innermost loop nest (`expValues` through `expCount`).
185  OpOperand *sparseOut;
186  // The count of outer non-filter loops, as defined by `isAdmissibleTopoOrder`.
187  LoopId outerParNest;
188  Value insChain;
189  Value expValues;
190  Value expFilled;
191  Value expAdded;
192  Value expCount;
193 
194  // Bookkeeping for reductions (up-to-date value of the reduction, and indices
195  // into the merger's expression tree. When the indices of a tensor reduction
196  // expression are exhausted, all inner loops can use a scalarized reduction.
197  Value redVal;
198  ExprId redExp;
199  ExprId redCustom;
200 
201  // Bookkeeping for lex insertion during reductions. Holds the runtime boolean
202  // value of whether any reduction occurred. This is only set during a
203  // reduction and cleared once the reduction is finished.
204  Value redValidLexInsert;
205 
206  // The root tensor expression of the kernel.
207  ExprId tensorExp;
208 };
209 
210 } // namespace sparse_tensor
211 } // namespace mlir
212 
213 #endif // MLIR_DIALECT_SPARSETENSOR_TRANSFORMS_UTILS_CODEGENENV_H_
This class represents an operand of an operation.
Definition: Value.h:267
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:96
The code generation environment class aggregates a number of data structures that are needed during t...
Definition: CodegenEnv.h:35
void startReduc(ExprId exp, Value val)
Definition: CodegenEnv.cpp:228
void updateValidLexInsert(Value val)
Definition: CodegenEnv.cpp:256
const SparsificationOptions & options() const
Definition: CodegenEnv.h:51
std::optional< Operation * > genLoopBoundary(function_ref< std::optional< Operation * >(MutableArrayRef< Value > parameters)> callback)
Generates loop boundary statements (entering/exiting loops).
Definition: CodegenEnv.cpp:103
ArrayRef< LatPointId > set(LatSetId s) const
Definition: CodegenEnv.h:83
bool isAdmissibleTensorExp(ExprId e)
Whether the tensor expression is admissible for codegen.
Definition: CodegenEnv.cpp:136
bool atExpandLevel(OpOperand *o, unsigned rank, LoopId n) const
Definition: CodegenEnv.cpp:200
CodegenEnv(linalg::GenericOp linop, SparsificationOptions opts, unsigned numTensors, unsigned numLoops, unsigned maxRank)
Constructs a code generation environment which can be passed around during sparsification for bookkee...
Definition: CodegenEnv.cpp:44
unsigned getCurrentDepth() const
Definition: CodegenEnv.h:115
std::pair< TensorId, Level > unpackTensorLevel(TensorLevel tl) const
Definition: CodegenEnv.h:107
TensorLevel makeTensorLevel(TensorId t, Level l) const
Definition: CodegenEnv.h:95
const LatPoint & lat(LatPointId l) const
Definition: CodegenEnv.h:82
constexpr TensorId makeTensorId(unsigned t) const
Definition: CodegenEnv.h:72
LevelType lt(TensorLoopId b) const
Definition: CodegenEnv.h:87
void startExpand(Value values, Value filled, Value added, Value count)
Definition: CodegenEnv.cpp:205
unsigned getLoopNum() const
Definition: CodegenEnv.h:89
void updateInsertionChain(Value chain)
Definition: CodegenEnv.cpp:195
bool generatingSparseIterator() const
Definition: CodegenEnv.h:52
void startCustomReduc(ExprId exp)
Definition: CodegenEnv.cpp:266
TensorLevel makeTensorLevel(std::pair< TensorId, Level > tlPair) const
Definition: CodegenEnv.h:104
constexpr TensorLoopId makeTensorLoopId(unsigned t, unsigned i) const
Definition: CodegenEnv.h:78
linalg::GenericOp op() const
Definition: CodegenEnv.h:50
Value getLoopVar(LoopId i) const
Returns the induction-variable for the given loop.
Definition: CodegenEnv.cpp:187
void startEmit(SparseEmitStrategy emitStrategy)
Definition: CodegenEnv.cpp:62
auto unpackTensorLevelRange(ContainerTy &&c) const
Definition: CodegenEnv.h:111
const TensorExp & exp(ExprId e) const
Definition: CodegenEnv.h:81
void updateExpandCount(Value count)
Definition: CodegenEnv.cpp:214
bool isSparseOutput(OpOperand *o) const
Definition: CodegenEnv.h:133
void startValidLexInsert(Value val)
Definition: CodegenEnv.cpp:251
constexpr LoopId makeLoopId(unsigned i) const
Definition: CodegenEnv.h:75
LevelType lt(TensorId t, LoopId i) const
Definition: CodegenEnv.h:84
TensorId getOutTensorId() const
Gets the TensorId for output tensor.
Definition: LoopEmitter.h:197
TensorLevel makeTensorLevel(TensorId t, Level l) const
Compresses a TensorId and Level into a TensorLevel.
Definition: LoopEmitter.h:203
unsigned getNumManifestTensors() const
Gets the total number of manifest tensors (excluding the synthetic tensor).
Definition: LoopEmitter.h:185
std::pair< TensorId, Level > unpackTensorLevel(TensorLevel tidLvl) const
De-compresses a TensorLevel back to a pair of TensorId and Level.
Definition: LoopEmitter.h:208
auto unpackTensorLevelRange(ContainerTy &&c) const
Converts a range of TensorLevel to a range of std::pair<TensorId, Level>
Definition: LoopEmitter.h:215
unsigned getNumTensors() const
Gets the total number of tensors that loopEmitter is operating on.
Definition: LoopEmitter.h:188
LoopId getCurrentDepth() const
Gets the current depth of the loop-stack.
Definition: LoopEmitter.h:172
TensorId getSynTensorId() const
Gets the TensorId for synthetic tensor.
Definition: LoopEmitter.h:194
A class to handle all iteration lattice operations.
Definition: Merger.h:225
constexpr unsigned getNumLoops() const
Gets the total number of loops (native loops + filter loops).
Definition: Merger.h:355
constexpr unsigned getNumTensors() const
Gets the total number of tensors (including the output-tensor and synthetic-tensor).
Definition: Merger.h:352
constexpr LoopId makeLoopId(unsigned i) const
Safely converts the argument to a loop identifier.
Definition: Merger.h:249
ArrayRef< LatPointId > set(LatSetId s) const
Definition: Merger.h:549
constexpr TensorId getSynTensorID() const
Gets the synthetic tensor's identifier (used for all invariant tensor expressions).
Definition: Merger.h:367
const TensorExp & exp(ExprId e) const
Convenience getters to immediately access the stored nodes.
Definition: Merger.h:541
const LatPoint & lat(LatPointId p) const
Definition: Merger.h:545
constexpr TensorId getOutTensorID() const
Gets the output tensor's identifier.
Definition: Merger.h:363
constexpr TensorId makeTensorId(unsigned t) const
Safely converts the argument to a tensor identifier.
Definition: Merger.h:243
LevelType getLvlType(TensorId t, LoopId i) const
Gets the level-type of the tth tensor on ith loop.
Definition: Merger.h:399
constexpr TensorLoopId makeTensorLoopId(unsigned t, unsigned i) const
Safely converts the arguments to a pair of (tensor,loop) identifiers.
Definition: Merger.h:255
static constexpr unsigned kInvalidId
A constant serving as the canonically invalid identifier, regardless of the identifier type.
Definition: Merger.h:30
unsigned LatSetId
LatSet identifiers.
Definition: Merger.h:57
unsigned TensorLevel
Definition: LoopEmitter.h:26
unsigned TensorLoopId
A compressed representation of std::pair<TensorId, LoopId>.
Definition: Merger.h:44
uint64_t Level
The type of level identifiers and level-ranks.
Definition: SparseTensor.h:42
unsigned LoopId
Loop identifiers.
Definition: Merger.h:38
unsigned ExprId
TensorExp identifiers.
Definition: Merger.h:48
unsigned LatPointId
LatPoint identifiers.
Definition: Merger.h:52
unsigned TensorId
Tensor identifiers, chosen to be the BlockArgument::getArgNumber of the value passed to Merger::build...
Definition: Merger.h:35
Include the generated interface declarations.
SparseEmitStrategy
Defines a scope for reinterpret map pass.
Definition: Passes.h:52
Options for the Sparsification pass.
Definition: Passes.h:93
SparseEmitStrategy sparseEmitStrategy
Definition: Passes.h:107
This enum defines all the sparse representations supportable by the SparseTensor dialect.
Definition: Enums.h:238
Tensor expression. Represents an MLIR expression in tensor index notation.
Definition: Merger.h:67