MLIR 24.0.0git
InferTypeOpInterface.h
Go to the documentation of this file.
1//===- InferTypeOpInterface.h - Infer Type Interfaces -----------*- 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 file contains the definitions of the infer op interfaces defined in
10// `InferTypeOpInterface.td`.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef MLIR_INTERFACES_INFERTYPEOPINTERFACE_H_
15#define MLIR_INTERFACES_INFERTYPEOPINTERFACE_H_
16
17#include "mlir/IR/Attributes.h"
18#include "mlir/IR/Builders.h"
20#include "mlir/IR/Location.h"
22#include "mlir/Support/LLVM.h"
23#include "llvm/ADT/PointerUnion.h"
24#include "llvm/ADT/SmallVector.h"
25
26namespace mlir {
27
30
31/// Reify the shape of the result of an operation (typically in terms of the
32/// shape of its operands).
33LogicalResult
35 ReifiedRankedShapedTypeDims &reifiedReturnShapes);
36FailureOr<SmallVector<OpFoldResult>>
37reifyShapeOfResult(OpBuilder &b, Operation *op, int resultIndex);
38FailureOr<OpFoldResult> reifyDimOfResult(OpBuilder &b, Operation *op,
39 int resultIndex, int dim);
40
41/// Adaptor class to abstract the differences between whether value is from
42/// a ShapedType or ShapedTypeComponents or DenseIntElementsAttribute.
44public:
46 if (auto st = dyn_cast<ShapedType>(t))
47 val = st;
48 }
50 if (auto da = dyn_cast<DenseIntElementsAttr>(t))
51 val = da;
52 }
53 ShapeAdaptor(ShapedTypeComponents *components) : val(components) {}
54 ShapeAdaptor(ShapedTypeComponents &components) : val(&components) {}
55
56 /// Returns whether the shape has a rank.
57 bool hasRank() const;
58
59 /// Returns the element type.
60 Type getElementType() const;
61
62 /// Populates the dimensions from shape referenced.
63 /// Requires: shape is ranked.
64 void getDims(SmallVectorImpl<int64_t> &res) const;
65
66 /// Populates the dimensions of the ShapeTypeComponents.
67 /// Requires: shape is ranked.
68 void getDims(ShapedTypeComponents &res) const;
69
70 /// Returns the size of the index'th dimension.
71 /// Requires: shape is ranked.
72 int64_t getDimSize(int index) const;
73
74 /// Returns whether the index'th dimension is dynamic.
75 /// Requires: shape is ranked.
76 bool isDynamicDim(int index) const {
77 return ShapedType::isDynamic(getDimSize(index));
78 }
79
80 /// Returns whether the shape is fully static.
81 bool hasStaticShape() const;
82
83 /// Returns the rank of the shape.
84 /// Requires: shape is ranked.
85 int64_t getRank() const;
86
87 /// Returns the number of elements in the shape.
88 /// Requires: hasStaticShape
89 int64_t getNumElements() const;
90
91 /// Returns whether valid (non-null) shape.
92 explicit operator bool() const { return !val.isNull(); }
93
94 /// Dumps textual repesentation to stderr.
95#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
96 LLVM_DUMP_METHOD void dump() const;
97#endif
98
99private:
100 // Union storing either ShapedTypeComponents, ShapedType (stored as Type and
101 // casted), or DenseIntElementsAttribute (stored as Atrtribute).
103};
104
105/// ShapedTypeComponents that represents the components of a ShapedType.
106/// The components consist of
107/// - A ranked or unranked shape with the dimension specification match those
108/// of ShapeType's getShape() (e.g., dynamic dimension represented using
109/// ShapedType::kDynamic)
110/// - A element type, may be unset (nullptr)
111/// - A attribute, may be unset (nullptr)
112/// Used by ShapedType type inferences.
114 /// Internal storage type for shape.
115 using ShapeStorageT = SmallVector<int64_t, 3>;
116
117public:
118 /// Default construction is an unranked shape.
119 ShapedTypeComponents() : elementType(nullptr), attr(nullptr) {};
121 : elementType(elementType), attr(nullptr), ranked(false) {}
122 ShapedTypeComponents(ShapedType shapedType) : attr(nullptr) {
123 ranked = shapedType.hasRank();
124 elementType = shapedType.getElementType();
125 if (ranked)
126 dims = llvm::to_vector<4>(shapedType.getShape());
127 }
129 ranked = adaptor.hasRank();
130 elementType = adaptor.getElementType();
131 if (ranked)
132 adaptor.getDims(*this);
133 }
134 template <typename Arg, typename = std::enable_if_t<
135 std::is_constructible<ShapeStorageT, Arg>::value>>
136 ShapedTypeComponents(Arg &&arg, Type elementType = nullptr,
137 Attribute attr = nullptr)
138 : dims(std::forward<Arg>(arg)), elementType(elementType), attr(attr),
139 ranked(true) {}
140 ShapedTypeComponents(ArrayRef<int64_t> vec, Type elementType = nullptr,
141 Attribute attr = nullptr)
142 : dims(vec.begin(), vec.end()), elementType(elementType), attr(attr),
143 ranked(true) {}
144
145 /// Return the dimensions of the shape.
146 /// Requires: shape is ranked.
148 assert(ranked && "requires ranked shape");
149 return dims;
150 }
151
152 /// Return whether the shape has a rank.
153 bool hasRank() const { return ranked; };
154
155 /// Return the element type component.
156 Type getElementType() const { return elementType; };
157
158 /// Return the raw attribute component.
159 Attribute getAttribute() const { return attr; };
160
161private:
162 friend class ShapeAdaptor;
163
164 ShapeStorageT dims;
165 Type elementType;
166 Attribute attr;
167 bool ranked{false};
168};
169
170/// Range of values and shapes (corresponding effectively to Shapes dialect's
171/// ValueShape type concept).
172// Currently this exposes the Value (of operands) and Type of the Value. This is
173// not ideal as then one can accidentally reference an out of date shape. This
174// is done to both enable gradual switch and also as OpAdaptor doesn't currently
175// allow returning anything other than Value.
176class ValueShapeRange : public ValueRange::RangeBaseT {
177public:
179
180 ValueShapeRange(ValueRange values, ValueShapeMapFn operandShape = nullptr,
181 ValueShapeMapFn valueToShape = nullptr)
182 : RangeBaseT(values), operandShape(operandShape),
183 valueToShape(valueToShape) {}
184 ValueShapeRange(const std::initializer_list<Value> &values)
185 : ValueShapeRange(ValueRange(values)) {}
186
188
189 /// Sets the Value to ShapeAdaptor mapping function and returns this.
191 valueToShape = fn;
192 return *this;
193 }
194
196 operandShape = fn;
197 return *this;
198 }
199
200 /// Returns the set Value to ShapeAdaptor mapping function.
201 ValueShapeMapFn getValueToShapeMapping() const { return valueToShape; }
202 ValueShapeMapFn getOperandShapeMapping() const { return operandShape; }
203
204 // Accessors.
205
206 /// Returns the types of the values within this range.
207 /// Note: This returns only the types of Values in the ValueRange and not a
208 /// more refined type.
211 type_range getTypes() const { return {begin(), end()}; }
212 auto getType() const { return getTypes(); }
213
214 /// Returns the Values in the ValueRange.
215 /// To query the most up to date shape of a Value, query the shape
216 /// using getShape below rather than using the type of the Value.
217 ValueRange getValues() const { return ValueRange(begin(), end()); };
218
219 /// Returns an argument as shape. If the argument is not constant or not a
220 /// shape, then the function returns a nullptr.
221 /// This will first query the valueToShape mapping (if set), before querying
222 /// the ValueRange.
224
225 /// Returns the shape of index'th operand.
226 // TODO: Update so that operator[] references these instead to avoid
227 // accidentally refering to less refined shape.
228 ShapeAdaptor getShape(int index) const;
229
230 /// Returns the shape of the given Value.
231 ShapeAdaptor getShape(Value val) const;
232
233private:
234 // Mapping from Value to ShapedTypeComponents corresponding to shape of type
235 // of Value.
236 ValueShapeMapFn operandShape;
237
238 // Mapping from Value to ShapedTypeComponents corresponding to constant Value
239 // if interpreted as shape.
240 ValueShapeMapFn valueToShape;
241};
242
243namespace detail {
244// Helper function to infer return tensor returns types given element and
245// shape inference function.
246LogicalResult
247inferReturnTensorTypes(ArrayRef<ShapedTypeComponents> retComponents,
248 SmallVectorImpl<Type> &inferredReturnTypes);
249
250/// Verifies that the inferred result types match the actual result types for
251/// the op. Precondition: op implements InferTypeOpInterface.
252LogicalResult verifyInferredResultTypes(Operation *op);
253
254/// Report a fatal error indicating that the result types could not be
255/// inferred.
256void reportFatalInferReturnTypesError(OperationState &state);
257} // namespace detail
258
259namespace OpTrait {
260template <typename ConcreteType>
261class InferTensorType;
262} // namespace OpTrait
263} // namespace mlir
264
265/// Include the generated interface declarations.
266#include "mlir/Interfaces/InferTypeOpInterface.h.inc"
267
268namespace mlir {
269namespace OpTrait {
270
271template <typename ConcreteType>
272class InferTypeOpAdaptor : public TraitBase<ConcreteType, InferTypeOpAdaptor> {
273};
274
275template <typename ConcreteType>
277 : public TraitBase<ConcreteType, InferShapedTypeOpAdaptor> {};
278
279/// Tensor type inference trait that constructs a tensor from the inferred
280/// shape and elemental types.
281/// Requires: Op implements InferShapedTypeOpInterface and InferTypeOpInterface.
282/// Less strict is possible (e.g., implements inferReturnTypeComponents and
283/// these always populates all element types and shapes or fails, but this
284/// trait is currently only used where the interfaces are, so keep it
285/// restricted for now).
286template <typename ConcreteType>
287class InferTensorType : public TraitBase<ConcreteType, InferTensorType> {};
288
289} // namespace OpTrait
290} // namespace mlir
291
292#endif // MLIR_INTERFACES_INFERTYPEOPINTERFACE_H_
true
Given two iterators into the same block, return "true" if a is before `b.
b
Return true if permutation is a valid permutation of the outer_dims_perm (case OuterOrInnerPerm::Oute...
false
Parses a map_entries map type from a string format back into its numeric value.
Attributes are known-constant values of operations.
Definition Attributes.h:25
This class helps build Operations.
Definition Builders.h:210
Tensor type inference trait that constructs a tensor from the inferred shape and elemental types.
Helper class for implementing traits.
Operation is the basic unit of execution within MLIR.
Definition Operation.h:87
Adaptor class to abstract the differences between whether value is from a ShapedType or ShapedTypeCom...
bool isDynamicDim(int index) const
Returns whether the index'th dimension is dynamic.
int64_t getDimSize(int index) const
Returns the size of the index'th dimension.
LLVM_DUMP_METHOD void dump() const
Dumps textual repesentation to stderr.
Type getElementType() const
Returns the element type.
int64_t getRank() const
Returns the rank of the shape.
bool hasStaticShape() const
Returns whether the shape is fully static.
ShapeAdaptor(ShapedTypeComponents &components)
ShapeAdaptor(ShapedTypeComponents *components)
int64_t getNumElements() const
Returns the number of elements in the shape.
void getDims(SmallVectorImpl< int64_t > &res) const
Populates the dimensions from shape referenced.
bool hasRank() const
Returns whether the shape has a rank.
ShapedTypeComponents that represents the components of a ShapedType.
ShapedTypeComponents()
Default construction is an unranked shape.
ShapedTypeComponents(Arg &&arg, Type elementType=nullptr, Attribute attr=nullptr)
ShapedTypeComponents(ShapedType shapedType)
ShapedTypeComponents(ArrayRef< int64_t > vec, Type elementType=nullptr, Attribute attr=nullptr)
ShapedTypeComponents(ShapeAdaptor adaptor)
bool hasRank() const
Return whether the shape has a rank.
Type getElementType() const
Return the element type component.
ArrayRef< int64_t > getDims() const
Return the dimensions of the shape.
Attribute getAttribute() const
Return the raw attribute component.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
This class provides an abstraction over the different types of ranges over Values.
Definition ValueRange.h:392
ValueTypeIterator< iterator > type_iterator
Returns the types of the values within this range.
ValueShapeRange & setOperandShapeMapping(ValueShapeMapFn fn)
ValueTypeRange< ValueRange > type_range
ValueShapeRange & setValueToShapeMapping(ValueShapeMapFn fn)
Sets the Value to ShapeAdaptor mapping function and returns this.
ValueShapeMapFn getOperandShapeMapping() const
ValueShapeMapFn getValueToShapeMapping() const
Returns the set Value to ShapeAdaptor mapping function.
ValueShapeRange(const ValueShapeRange &)=default
ShapeAdaptor getValueAsShape(int index)
Returns an argument as shape.
type_range getTypes() const
ValueShapeRange(ValueRange values, ValueShapeMapFn operandShape=nullptr, ValueShapeMapFn valueToShape=nullptr)
ValueShapeRange(const std::initializer_list< Value > &values)
ShapeAdaptor getShape(int index) const
Returns the shape of index'th operand.
function_ref< ShapeAdaptor(Value)> ValueShapeMapFn
ValueRange getValues() const
Returns the Values in the ValueRange.
This class implements iteration on the types of a given range of values.
Definition TypeRange.h:134
This class implements iteration on the types of a given range of values.
Definition TypeRange.h:147
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
LogicalResult inferReturnTensorTypes(ArrayRef< ShapedTypeComponents > retComponents, SmallVectorImpl< Type > &inferredReturnTypes)
void reportFatalInferReturnTypesError(OperationState &state)
Report a fatal error indicating that the result types could not be inferred.
LogicalResult verifyInferredResultTypes(Operation *op)
Verifies that the inferred result types match the actual result types for the op.
Include the generated interface declarations.
LogicalResult reifyResultShapes(OpBuilder &b, Operation *op, ReifiedRankedShapedTypeDims &reifiedReturnShapes)
Reify the shape of the result of an operation (typically in terms of the shape of its operands).
FailureOr< OpFoldResult > reifyDimOfResult(OpBuilder &b, Operation *op, int resultIndex, int dim)
SmallVector< SmallVector< OpFoldResult > > ReifiedRankedShapedTypeDims
llvm::function_ref< Fn > function_ref
Definition LLVM.h:155
FailureOr< SmallVector< OpFoldResult > > reifyShapeOfResult(OpBuilder &b, Operation *op, int resultIndex)