22 :
public ValueBoundsOpInterface::ExternalModel<CastOpInterface, CastOp> {
23 void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
24 ValueBoundsConstraintSet &cstr)
const {
25 auto castOp = cast<CastOp>(op);
26 assert(value == castOp.getResult() &&
"invalid value");
28 if (llvm::isa<RankedTensorType>(castOp.getResult().getType()) &&
29 llvm::isa<RankedTensorType>(castOp.getSource().getType())) {
30 cstr.
bound(value)[dim] == cstr.
getExpr(castOp.getSource(), dim);
35struct CollapseShapeOpInterface
36 :
public ValueBoundsOpInterface::ExternalModel<CollapseShapeOpInterface,
38 void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
39 ValueBoundsConstraintSet &cstr)
const {
40 auto collapseOp = cast<CollapseShapeOp>(op);
41 assert(value == collapseOp.getResult() &&
"invalid value");
45 collapseOp.getReassociationIndices()[dim];
46 AffineExpr productExpr =
47 cstr.
getExpr(collapseOp.getSrc(), reassocIndices[0]);
48 for (
size_t i = 1; i < reassocIndices.size(); ++i) {
50 productExpr * cstr.
getExpr(collapseOp.getSrc(), reassocIndices[i]);
52 cstr.
bound(value)[dim] == productExpr;
56struct ConcatOpInterface
57 :
public ValueBoundsOpInterface::ExternalModel<ConcatOpInterface,
59 void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
60 ValueBoundsConstraintSet &cstr)
const {
61 auto concatOp = cast<ConcatOp>(op);
62 assert(value == concatOp.getResult() &&
"invalid value");
65 if (dim !=
static_cast<int64_t
>(concatOp.getDim())) {
69 for (Value input : inputs)
75 AffineExpr sum = cstr.
getExpr(inputs.front(), dim);
76 for (Value input : inputs.drop_front())
77 sum = sum + cstr.
getExpr(input, dim);
78 cstr.
bound(value)[dim] == sum;
83 :
public ValueBoundsOpInterface::ExternalModel<DimOpInterface, DimOp> {
84 void populateBoundsForIndexValue(Operation *op, Value value,
85 ValueBoundsConstraintSet &cstr)
const {
86 auto dimOp = cast<DimOp>(op);
87 assert(value == dimOp.getResult() &&
"invalid value");
89 cstr.
bound(value) >= 0;
90 auto constIndex = dimOp.getConstantIndex();
91 if (!constIndex.has_value())
93 cstr.
bound(value) == cstr.
getExpr(dimOp.getSource(), *constIndex);
97struct EmptyOpInterface
98 :
public ValueBoundsOpInterface::ExternalModel<EmptyOpInterface, EmptyOp> {
99 void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
100 ValueBoundsConstraintSet &cstr)
const {
101 auto emptyOp = cast<EmptyOp>(op);
102 assert(value == emptyOp.getResult() &&
"invalid value");
104 cstr.
bound(value)[dim] == emptyOp.getMixedSizes()[dim];
108struct ExpandShapeOpInterface
109 :
public ValueBoundsOpInterface::ExternalModel<ExpandShapeOpInterface,
111 void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
112 ValueBoundsConstraintSet &cstr)
const {
113 auto expandOp = cast<ExpandShapeOp>(op);
114 assert(value == expandOp.getResult() &&
"invalid value");
115 cstr.
bound(value)[dim] == expandOp.getMixedOutputShape()[dim];
119struct ExtractSliceOpInterface
120 :
public ValueBoundsOpInterface::ExternalModel<ExtractSliceOpInterface,
122 void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
123 ValueBoundsConstraintSet &cstr)
const {
124 auto extractSliceOp = cast<ExtractSliceOp>(op);
125 assert(value == extractSliceOp.getResult() &&
"invalid value");
127 llvm::SmallBitVector dropped = extractSliceOp.getDroppedDims();
129 for (int64_t i = 0, e = extractSliceOp.getMixedSizes().size(); i < e; ++i) {
131 if (!dropped.test(i))
134 cstr.
bound(value)[dim] == extractSliceOp.getMixedSizes()[i];
138 llvm_unreachable(
"could not find non-rank-reduced dim");
143 :
public ValueBoundsOpInterface::ExternalModel<PadOpInterface, PadOp> {
144 void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
145 ValueBoundsConstraintSet &cstr)
const {
146 auto padOp = cast<PadOp>(op);
147 assert(value == padOp.getResult() &&
"invalid value");
149 AffineExpr srcSize = cstr.
getExpr(padOp.getSource(), dim);
150 AffineExpr lowPad = cstr.
getExpr(padOp.getMixedLowPad()[dim]);
151 AffineExpr highPad = cstr.
getExpr(padOp.getMixedHighPad()[dim]);
152 cstr.
bound(value)[dim] == srcSize + lowPad + highPad;
156struct RankOpInterface
157 :
public ValueBoundsOpInterface::ExternalModel<RankOpInterface, RankOp> {
158 void populateBoundsForIndexValue(Operation *op, Value value,
159 ValueBoundsConstraintSet &cstr)
const {
160 auto rankOp = cast<RankOp>(op);
161 assert(value == rankOp.getResult() &&
"invalid value");
164 llvm::dyn_cast<RankedTensorType>(rankOp.getTensor().getType());
167 cstr.
bound(value) == tensorType.getRank();
171struct SplatOpInterface
172 :
public ValueBoundsOpInterface::ExternalModel<SplatOpInterface, SplatOp> {
173 void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
174 ValueBoundsConstraintSet &cstr)
const {
175 auto splatOp = cast<SplatOp>(op);
176 assert(value == splatOp.getAggregate() &&
"invalid value");
178 RankedTensorType type = splatOp.getType();
180 type.getShape(), splatOp.getDynamicSizes(), type.getContext());
181 cstr.
bound(value)[dim] == sizes[dim];
192 tensor::CastOp::attachInterface<tensor::CastOpInterface>(*ctx);
193 tensor::CollapseShapeOp::attachInterface<tensor::CollapseShapeOpInterface>(
195 tensor::ConcatOp::attachInterface<tensor::ConcatOpInterface>(*ctx);
196 tensor::DimOp::attachInterface<tensor::DimOpInterface>(*ctx);
197 tensor::EmptyOp::attachInterface<tensor::EmptyOpInterface>(*ctx);
198 tensor::ExpandShapeOp::attachInterface<tensor::ExpandShapeOpInterface>(
200 tensor::ExtractSliceOp::attachInterface<tensor::ExtractSliceOpInterface>(
202 tensor::PadOp::attachInterface<tensor::PadOpInterface>(*ctx);
203 tensor::RankOp::attachInterface<tensor::RankOpInterface>(*ctx);
204 tensor::SplatOp::attachInterface<tensor::SplatOpInterface>(*ctx);
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
MLIRContext is the top-level object for a collection of MLIR operations.
AffineExpr getExpr(Value value, std::optional< int64_t > dim=std::nullopt)
Return an expression that represents the given index-typed value or shaped value dimension.
BoundBuilder bound(Value value)
Add a bound for the given index-typed value or shaped value.
void registerValueBoundsOpInterfaceExternalModels(DialectRegistry ®istry)
Include the generated interface declarations.
SmallVector< OpFoldResult > getMixedValues(ArrayRef< int64_t > staticValues, ValueRange dynamicValues, MLIRContext *context)
Return a vector of OpFoldResults with the same size a staticValues, but all elements for which Shaped...
SmallVector< int64_t, 2 > ReassociationIndices