28 struct PadOpTiling :
public TilingInterface::ExternalModel<PadOpTiling, PadOp> {
31 auto padOp = cast<PadOp>(op);
33 padOp.getResultType().getRank(), utils::IteratorType::parallel);
45 for (
const auto &ub :
enumerate(reifiedShapes[0]))
46 loopRanges[ub.index()].size = ub.value();
50 FailureOr<TilingResult>
54 FailureOr<TilingResult> result =
58 return result.value();
67 resultOffsets.assign(offsets.begin(), offsets.end());
68 resultSizes.assign(sizes.begin(), sizes.end());
72 LogicalResult getIterationDomainTileFromResultTile(
77 iterDomainOffsets.assign(offsets.begin(), offsets.end());
78 iterDomainSizes.assign(sizes.begin(), sizes.end());
82 FailureOr<TilingResult>
96 bool generateZeroSliceGuard) {
98 Value padValue = padOp.getConstantPaddingValue();
128 bool hasZeroLen =
false;
131 Value dynHasZeroLenCond;
133 int64_t rank = padOp.getSourceType().getRank();
136 for (
unsigned dim = 0; dim < rank; ++dim) {
137 auto low = padOp.getMixedLowPad()[dim];
139 auto high = padOp.getMixedHighPad()[dim];
141 auto offset = offsets[dim];
142 auto length = sizes[dim];
145 if (!hasLowPad && !hasHighPad) {
146 newOffsets.push_back(offset);
147 newLengths.push_back(length);
148 newLows.push_back(low);
149 newHighs.push_back(high);
161 newLows.push_back(newLow);
176 ?
min(
max(sub(offset, low), zero), srcSize)
177 :
min(offset, srcSize);
178 newOffsets.push_back(newOffset);
202 OpFoldResult newLength =
min(sub(srcSize, newOffset), sub(length, newLow));
206 newLength =
max(newLength, zero);
207 newLengths.push_back(newLength);
213 }
else if (!hasZeroLen) {
215 loc, arith::CmpIPredicate::eq,
220 ? b.
create<arith::OrIOp>(loc, check, dynHasZeroLenCond)
229 hasHighPad ? sub(sub(length, newLength), newLow) : zero;
230 newHighs.push_back(newHigh);
237 RankedTensorType resultType =
242 if (resultType == val.getType())
244 return b.
create<tensor::CastOp>(loc, resultType, val);
250 auto createGenerateOp = [&]() {
252 auto generateOp = b.
create<tensor::GenerateOp>(
253 loc, resultType, dynDims,
255 builder.create<tensor::YieldOp>(gLoc, padValue);
262 auto createPadOfExtractSlice = [&]() {
264 auto newSliceOp = b.
create<tensor::ExtractSliceOp>(
265 loc, padOp.getSource(), newOffsets, newLengths, newStrides);
266 auto newPadOp = b.
create<PadOp>(
267 loc,
Type(), newSliceOp, newLows, newHighs,
273 padOp.getRegion().cloneInto(&newPadOp.getRegion(), bvm);
276 return std::make_tuple(newPadOp, newSliceOp);
282 Operation *generateOp = createGenerateOp();
290 if (generateZeroSliceGuard && dynHasZeroLenCond) {
294 auto result = b.
create<scf::IfOp>(
295 loc, dynHasZeroLenCond,
298 thenOp = createGenerateOp();
299 b.create<scf::YieldOp>(loc, castResult(thenOp->
getResult(0)));
303 std::tie(elseOp, sliceOp) = createPadOfExtractSlice();
304 b.create<scf::YieldOp>(loc, castResult(elseOp->
getResult(0)));
310 auto [newPadOp, sliceOp] = createPadOfExtractSlice();
312 {newPadOp}, {castResult(newPadOp->getResult(0))}, {sliceOp}};
318 tensor::PadOp::attachInterface<PadOpTiling>(*ctx);
static Value max(ImplicitLocOpBuilder &builder, Value value, Value bound)
static Value min(ImplicitLocOpBuilder &builder, Value value, Value bound)
static LogicalResult getResultTilePosition(RewriterBase &rewriter, int64_t index, Value tiledResult, TilingInterface op, ArrayRef< OpFoldResult > offsets, ArrayRef< OpFoldResult > sizes, SmallVector< OpFoldResult > &resultOffset, SmallVector< OpFoldResult > &resultSize, const scf::SCFTilingOptions &options)
static FailureOr< TilingResult > getTiledImplementation(RewriterBase &rewriter, TilingInterface op, ValueRange regionIterArg, ArrayRef< OpFoldResult > offsets, ArrayRef< OpFoldResult > sizes, const scf::SCFTilingOptions &options)
Base type for affine expression.
static AffineMap getMultiDimIdentityMap(unsigned numDims, MLIRContext *context)
Returns an AffineMap with 'numDims' identity result dim exprs.
static AffineMap get(MLIRContext *context)
Returns a zero result affine map with no dimensions or symbols: () -> ().
IntegerAttr getIndexAttr(int64_t value)
MLIRContext * getContext() const
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.
This is a utility class for mapping one set of IR entities to another.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
This class helps build Operations.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
This class represents a single result from folding an operation.
Operation is the basic unit of execution within MLIR.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
OpFoldResult makeComposedFoldedAffineMax(OpBuilder &b, Location loc, AffineMap map, ArrayRef< OpFoldResult > operands)
Constructs an AffineMinOp that computes a maximum across the results of applying map to operands,...
OpFoldResult makeComposedFoldedAffineMin(OpBuilder &b, Location loc, AffineMap map, ArrayRef< OpFoldResult > operands)
Constructs an AffineMinOp that computes a minimum across the results of applying map to operands,...
OpFoldResult makeComposedFoldedAffineApply(OpBuilder &b, Location loc, AffineMap map, ArrayRef< OpFoldResult > operands)
Constructs an AffineApplyOp that applies map to operands after composing the map with the maps of any...
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
FailureOr< TilingResult > bubbleUpPadSlice(OpBuilder &b, tensor::PadOp padOp, ArrayRef< OpFoldResult > offsets, ArrayRef< OpFoldResult > sizes, bool generateZeroSliceGuard=true)
Bubbles up a slice of this pad by taking the slice first and then performing the padding.
void registerTilingInterfaceExternalModels(mlir::DialectRegistry ®istry)
Registers external models for Tiling interface for tensor ops.
OpFoldResult getMixedSize(OpBuilder &builder, Location loc, Value value, int64_t dim)
Return the dimension of the given tensor value.
Include the generated interface declarations.
bool isConstantIntValue(OpFoldResult ofr, int64_t value)
Return true if ofr is constant integer equal to value.
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).
void bindDims(MLIRContext *ctx, AffineExprTy &...exprs)
Bind a list of AffineExpr references to DimExpr at positions: [0 .
void dispatchIndexOpFoldResults(ArrayRef< OpFoldResult > ofrs, SmallVectorImpl< Value > &dynamicVec, SmallVectorImpl< int64_t > &staticVec)
Helper function to dispatch multiple OpFoldResults according to the behavior of dispatchIndexOpFoldRe...
Value getValueOrCreateConstantIndexOp(OpBuilder &b, Location loc, OpFoldResult ofr)
Converts an OpFoldResult to a Value.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
SmallVector< NamedAttribute > getPrunedAttributeList(Operation *op, ArrayRef< StringRef > elidedAttrs)
Container for result values of tiling.