MLIR 22.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
25namespace mlir {
26namespace 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.
36public:
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; }
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); }
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
169private:
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_
b
Return true if permutation is a valid permutation of the outer_dims_perm (case OuterOrInnerPerm::Oute...
This class represents an operand of an operation.
Definition Value.h:257
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
void startReduc(ExprId exp, Value val)
std::optional< Operation * > genLoopBoundary(function_ref< std::optional< Operation * >(MutableArrayRef< Value > parameters)> callback)
Generates loop boundary statements (entering/exiting loops).
bool isAdmissibleTensorExp(ExprId e)
Whether the tensor expression is admissible for codegen.
bool atExpandLevel(OpOperand *o, unsigned rank, LoopId n) const
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...
ArrayRef< LatPointId > set(LatSetId s) const
Definition CodegenEnv.h:83
unsigned getCurrentDepth() const
Definition CodegenEnv.h:115
TensorLevel makeTensorLevel(TensorId t, Level l) const
Definition CodegenEnv.h:95
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)
void updateInsertionChain(Value chain)
bool generatingSparseIterator() const
Definition CodegenEnv.h:52
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.
void startEmit(SparseEmitStrategy emitStrategy)
auto unpackTensorLevelRange(ContainerTy &&c) const
Definition CodegenEnv.h:111
void updateExpandCount(Value count)
bool isSparseOutput(OpOperand *o) const
Definition CodegenEnv.h:133
constexpr LoopId makeLoopId(unsigned i) const
Definition CodegenEnv.h:75
std::pair< TensorId, Level > unpackTensorLevel(TensorLevel tl) const
Definition CodegenEnv.h:107
const TensorExp & exp(ExprId e) const
Definition CodegenEnv.h:81
const SparsificationOptions & options() const
Definition CodegenEnv.h:51
LevelType lt(TensorId t, LoopId i) const
Definition CodegenEnv.h:84
const LatPoint & lat(LatPointId l) const
Definition CodegenEnv.h:82
A class to handle all iteration lattice operations.
Definition Merger.h:225
static constexpr unsigned kInvalidId
A constant serving as the canonically invalid identifier, regardless of the identifier type.
Definition Merger.h:30
unsigned LatPointId
LatPoint identifiers.
Definition Merger.h:52
unsigned ExprId
TensorExp identifiers.
Definition Merger.h:48
unsigned TensorId
Tensor identifiers, chosen to be the BlockArgument::getArgNumber of the value passed to Merger::build...
Definition Merger.h:35
uint64_t Level
The type of level identifiers and level-ranks.
unsigned TensorLoopId
A compressed representation of std::pair<TensorId, LoopId>.
Definition Merger.h:44
unsigned LoopId
Loop identifiers.
Definition Merger.h:38
unsigned LatSetId
LatSet identifiers.
Definition Merger.h:57
Include the generated interface declarations.
SparseEmitStrategy
Defines a scope for reinterpret map pass.
Definition Passes.h:52
llvm::function_ref< Fn > function_ref
Definition LLVM.h:152
Options for the Sparsification pass.
Definition Passes.h:108
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