@@ -18,7 +18,6 @@ include "mlir/Interfaces/ControlFlowInterfaces.td"
18
18
include "mlir/Interfaces/InferTypeOpInterface.td"
19
19
include "mlir/Interfaces/LoopLikeInterface.td"
20
20
include "mlir/Interfaces/SideEffectInterfaces.td"
21
- include "mlir/Interfaces/TilingInterface.td"
22
21
include "mlir/Interfaces/ViewLikeInterface.td"
23
22
24
23
// Base class for Linalg dialect ops that do not correspond to library calls.
@@ -130,207 +129,6 @@ def Linalg_InitTensorOp : Linalg_Op<"init_tensor",
130
129
let hasCanonicalizer = 1;
131
130
}
132
131
133
- def Linalg_PadTensorOp : Linalg_Op<"pad_tensor",
134
- [AttrSizedOperandSegments, NoSideEffect,
135
- DeclareOpInterfaceMethods<ReifyRankedShapedTypeOpInterface>,
136
- DeclareOpInterfaceMethods<TilingInterface,
137
- ["getDestinationOperands", "getLoopIteratorTypes", "getIterationDomain",
138
- "getTiledImplementation"]>]> {
139
- let summary = "tensor pad operation";
140
- let description = [{
141
- `linalg.pad_tensor` is an operation that pads the `source` tensor
142
- with given `low` and `high` padding config.
143
-
144
- The PadTensor operation supports the following arguments:
145
-
146
- * source: the "base" tensor on which to pad.
147
- * low: A list contains the padding along the start of each
148
- dimension, i.e `low`.
149
- * high: A list contains the padding along the end of each
150
- dimension, i.e. `high`.
151
- * nofold: indicates that the operation should not be folded when source and
152
- result types are equal.
153
-
154
- The result tensor dimensions are `low` + `dim` + `high` along that
155
- dimension. The number of elements of `low` and `high` must match
156
- the rank of the input tensor. They can be either a constant or a
157
- dynamic value.
158
-
159
- The region of the `pad_tensor` operation returns the value to use
160
- for the padding. The arguments of the region represent the index
161
- of the source being accessed. There should be as many arguments as
162
- the rank of the `source` tensor. The value `yield`-ed by the
163
- region is used as the value of the view at the given position.
164
-
165
- If `nofold` is set, the padding operation will not be folded away even
166
- if the source type and the padded type have the same static shape. This can
167
- be used, e.g., for packing or promotion to faster memory.
168
-
169
- Example 1:
170
-
171
- ```mlir
172
- %pad_value = ... : f32
173
- %0 = linalg.pad_tensor %0 low[1, 2] high[2, 3] {
174
- ^bb0(%arg0 : index, %arg1 : index):
175
- linalg.yield %pad_value : f32
176
- } : tensor<?x?xf32> to tensor<?x?xf32>
177
- ```
178
-
179
- Example 2:
180
-
181
- ```mlir
182
- %pad_value = ... : f32
183
- %0 = linalg.pad_tensor %arg0 low[2, %arg1, 3, 3] high[3, 3, %arg1, 2] {
184
- ^bb0(%arg2: index, %arg3: index, %arg4: index, %arg5: index):
185
- linalg.yield %pad_value : f32
186
- } : tensor<1x2x2x?xf32> to tensor<6x?x?x?xf32>
187
- ```
188
-
189
- Example 3:
190
-
191
- ```mlir
192
- %pad_value = ... : f32
193
- %0 = linalg.pad_tensor %arg0 low[0, 0] high[%ub0, %ub1] {
194
- ^bb0(%arg1: index, %arg2: index):
195
- linalg.yield %pad_value : f32
196
- } : tensor<2x3xf32> to tensor<?x?xf32>
197
- ```
198
-
199
- Example 4:
200
-
201
- ```mlir
202
- // Force a padded value to be always exist with `nofold`.
203
- %pad_value = ... : f32
204
- %0 = linalg.pad_tensor %arg0 nofold low[0, 0] high[0, 0] {
205
- ^bb0(%arg1: index, %arg2: index):
206
- linalg.yield %pad_value : f32
207
- } : tensor<2x3xf32> to tensor<2x3xf32>
208
- ```
209
- }];
210
-
211
- let arguments = (ins
212
- AnyTensor:$source,
213
- Variadic<Index>:$low,
214
- Variadic<Index>:$high,
215
- I64ArrayAttr:$static_low,
216
- I64ArrayAttr:$static_high,
217
- UnitAttr:$nofold);
218
-
219
- let regions = (region SizedRegion<1>:$region);
220
-
221
- let results = (outs AnyTensor:$result);
222
-
223
- // TODO: Remove custom<InferType> when AllTypesMatch supports opt. operands.
224
- let assemblyFormat = [{
225
- $source
226
- (`nofold` $nofold^)?
227
- `low` `` custom<OperandsOrIntegersSizesList>($low, $static_low)
228
- `high` `` custom<OperandsOrIntegersSizesList>($high, $static_high)
229
- $region attr-dict `:` type($source) `to` type($result)
230
- }];
231
-
232
- let extraClassDeclaration = [{
233
- static StringRef getStaticLowAttrName() {
234
- return "static_low";
235
- }
236
-
237
- static StringRef getStaticHighAttrName() {
238
- return "static_high";
239
- }
240
-
241
- RankedTensorType getSourceType() {
242
- return source().getType().cast<RankedTensorType>();
243
- }
244
- RankedTensorType getResultType() {
245
- return getResult().getType().cast<RankedTensorType>();
246
- }
247
-
248
- // Infer the shape of the result tensor given the type of the source tensor
249
- // and paddings. Known result dimensions that cannot necessarily be inferred
250
- // from low/high padding sizes can be optionally specified. Those will be
251
- // considered when computing the result type.
252
- static RankedTensorType inferResultType(
253
- RankedTensorType sourceType,
254
- ArrayRef<int64_t> staticLow,
255
- ArrayRef<int64_t> staticHigh,
256
- ArrayRef<int64_t> resultShape = {});
257
-
258
- // Return a PadTensorOp that pads `source` to `type` size where the static
259
- // sizes are assumed to be greater than the dynamic sizes. The op performs
260
- // "high" padding (i.e. it adds trailing padding values until the desired
261
- // size is met).
262
- static linalg::PadTensorOp createPadHighOp(
263
- Type type, Value source, Value pad, bool nofold, Location loc,
264
- OpBuilder & builder);
265
-
266
- // Return a PadTensorOp that pads `source to `type` size with `pad` value.
267
- // I.e., a block will be created and the `pad` value will be yielded
268
- // directly. If the type passed is nullptr, it is inferred.
269
- static linalg::PadTensorOp createPadScalarOp(
270
- Type type, Value source, Value pad, ArrayRef<OpFoldResult> low,
271
- ArrayRef<OpFoldResult> high, bool nofold, Location loc,
272
- OpBuilder & builder);
273
-
274
- // Return the pad value if it is a constant. Return null value otherwise.
275
- Value getConstantPaddingValue();
276
-
277
- // Return a vector of all the static or dynamic values (low/high padding) of
278
- // the op.
279
- inline SmallVector<OpFoldResult> getMixedPadImpl(ArrayAttr staticAttrs,
280
- ValueRange values) {
281
- SmallVector<OpFoldResult> res;
282
- unsigned numDynamic = 0;
283
- unsigned count = staticAttrs.size();
284
- for (unsigned idx = 0; idx < count; ++idx) {
285
- if (ShapedType::isDynamic(staticAttrs[idx].cast<IntegerAttr>().getInt()))
286
- res.push_back(values[numDynamic++]);
287
- else
288
- res.push_back(staticAttrs[idx]);
289
- }
290
- return res;
291
- }
292
- SmallVector<OpFoldResult> getMixedLowPad() {
293
- return getMixedPadImpl(static_low(), low());
294
- }
295
- SmallVector<OpFoldResult> getMixedHighPad() {
296
- return getMixedPadImpl(static_high(), high());
297
- }
298
- // Return true if low padding is guaranteed to be 0.
299
- bool hasZeroLowPad() {
300
- return llvm::all_of(getMixedLowPad(), [](OpFoldResult ofr) {
301
- return getConstantIntValue(ofr) == static_cast<int64_t>(0);
302
- });
303
- }
304
- // Return true if high padding is guaranteed to be 0.
305
- bool hasZeroHighPad() {
306
- return llvm::all_of(getMixedHighPad(), [](OpFoldResult ofr) {
307
- return getConstantIntValue(ofr) == static_cast<int64_t>(0);
308
- });
309
- }
310
- }];
311
-
312
- let builders = [
313
- // Build a PadTensorOp with mixed static and dynamic entries.
314
- OpBuilder<(ins "Value":$source, "ArrayRef<int64_t>":$staticLow,
315
- "ArrayRef<int64_t>":$staticHigh, "ValueRange":$low, "ValueRange":$high,
316
- CArg<"bool", "false">:$nofold,
317
- CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs)>,
318
- // Build a PadTensorOp with all dynamic entries.
319
- OpBuilder<(ins "Value":$source, "ValueRange":$low, "ValueRange":$high,
320
- CArg<"bool", "false">:$nofold,
321
- CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs)>,
322
- // Build a PadTensorOp with mixed static and dynamic entries and custom
323
- // result type. If the type passed is nullptr, it is inferred.
324
- OpBuilder<(ins "Type":$resultType, "Value":$source,
325
- "ArrayRef<OpFoldResult>":$low, "ArrayRef<OpFoldResult>":$high,
326
- CArg<"bool", "false">:$nofold,
327
- CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs)>,
328
- ];
329
-
330
- let hasCanonicalizer = 1;
331
- let hasFolder = 1;
332
- }
333
-
334
132
def Linalg_YieldOp : Linalg_Op<"yield", [NoSideEffect, ReturnLike, Terminator]>,
335
133
Arguments<(ins Variadic<AnyType>:$values)> {
336
134
let summary = "Linalg yield operation";
0 commit comments