Skip to content

Commit

Permalink
[MLIR] Adopt DenseI64ArrayAttr in tensor, memref and linalg transform
Browse files Browse the repository at this point in the history
This commit is a first step toward removing inconsistencies between dynamic
and static attributes (i64 v. index) by dropping `I64ArrayAttr` and
using `DenseI64ArrayAttr` in Tensor, Memref and Linalg Transform ops.
In Linalg Transform ops only `TileToScfForOp` and `TileOp` have been updated.

See related discussion: https://discourse.llvm.org/t/rfc-inconsistency-between-dynamic-and-static-attributes-i64-v-index/66612/1

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D138567
  • Loading branch information
chelini committed Nov 25, 2022
1 parent 36f61d1 commit a9733b8
Show file tree
Hide file tree
Showing 18 changed files with 253 additions and 236 deletions.
Expand Up @@ -839,8 +839,8 @@ def TileOp : Op<Transform_Dialect, "structured.tile",

let arguments = (ins PDL_Operation:$target,
Variadic<PDL_Operation>:$dynamic_sizes,
DefaultValuedAttr<I64ArrayAttr, "{}">:$static_sizes,
DefaultValuedAttr<I64ArrayAttr, "{}">:$interchange);
DefaultValuedOptionalAttr<DenseI64ArrayAttr, "{}">:$static_sizes,
DefaultValuedOptionalAttr<DenseI64ArrayAttr, "{}">:$interchange);
let results = (outs PDL_Operation:$tiled_linalg_op,
Variadic<PDL_Operation>:$loops);

Expand Down Expand Up @@ -917,8 +917,8 @@ def TileToForeachThreadOp :
let arguments = (ins PDL_Operation:$target,
Variadic<PDL_Operation>:$num_threads,
Variadic<PDL_Operation>:$tile_sizes,
DefaultValuedAttr<I64ArrayAttr, "{}">:$static_num_threads,
DefaultValuedAttr<I64ArrayAttr, "{}">:$static_tile_sizes,
DefaultValuedOptionalAttr<DenseI64ArrayAttr, "{}">:$static_num_threads,
DefaultValuedOptionalAttr<DenseI64ArrayAttr, "{}">:$static_tile_sizes,
OptionalAttr<DeviceMappingArrayAttr>:$mapping);
let results = (outs PDL_Operation:$foreach_thread_op,
PDL_Operation:$tiled_op);
Expand Down Expand Up @@ -1009,8 +1009,8 @@ def TileToScfForOp : Op<Transform_Dialect, "structured.tile_to_scf_for",

let arguments = (ins PDL_Operation:$target,
Variadic<PDL_Operation>:$dynamic_sizes,
DefaultValuedAttr<I64ArrayAttr, "{}">:$static_sizes,
DefaultValuedAttr<I64ArrayAttr, "{}">:$interchange);
DefaultValuedOptionalAttr<DenseI64ArrayAttr, "{}">:$static_sizes,
DefaultValuedOptionalAttr<DenseI64ArrayAttr, "{}">:$interchange);
let results = (outs PDL_Operation:$tiled_linalg_op,
Variadic<PDL_Operation>:$loops);

Expand Down
16 changes: 8 additions & 8 deletions mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td
Expand Up @@ -1260,9 +1260,9 @@ def MemRef_ReinterpretCastOp
Variadic<Index>:$offsets,
Variadic<Index>:$sizes,
Variadic<Index>:$strides,
I64ArrayAttr:$static_offsets,
I64ArrayAttr:$static_sizes,
I64ArrayAttr:$static_strides);
DenseI64ArrayAttr:$static_offsets,
DenseI64ArrayAttr:$static_sizes,
DenseI64ArrayAttr:$static_strides);
let results = (outs AnyMemRef:$result);

let assemblyFormat = [{
Expand Down Expand Up @@ -1476,7 +1476,7 @@ def MemRef_ExpandShapeOp : MemRef_ReassociativeReshapeOp<"expand_shape", [
or copies.

A reassociation is defined as a grouping of dimensions and is represented
with an array of I64ArrayAttr attributes.
with an array of DenseI64ArrayAttr attributes.

Example:

Expand Down Expand Up @@ -1563,7 +1563,7 @@ def MemRef_CollapseShapeOp : MemRef_ReassociativeReshapeOp<"collapse_shape", [
type.

A reassociation is defined as a continuous grouping of dimensions and is
represented with an array of I64ArrayAttr attribute.
represented with an array of DenseI64ArrayAttr attribute.

Note: Only the dimensions within a reassociation group must be contiguous.
The remaining dimensions may be non-contiguous.
Expand Down Expand Up @@ -1855,9 +1855,9 @@ def SubViewOp : MemRef_OpWithOffsetSizesAndStrides<"subview", [
Variadic<Index>:$offsets,
Variadic<Index>:$sizes,
Variadic<Index>:$strides,
I64ArrayAttr:$static_offsets,
I64ArrayAttr:$static_sizes,
I64ArrayAttr:$static_strides);
DenseI64ArrayAttr:$static_offsets,
DenseI64ArrayAttr:$static_sizes,
DenseI64ArrayAttr:$static_strides);
let results = (outs AnyMemRef:$result);

let assemblyFormat = [{
Expand Down
37 changes: 19 additions & 18 deletions mlir/include/mlir/Dialect/Tensor/IR/TensorOps.td
Expand Up @@ -326,9 +326,9 @@ def Tensor_ExtractSliceOp : Tensor_OpWithOffsetSizesAndStrides<"extract_slice",
Variadic<Index>:$offsets,
Variadic<Index>:$sizes,
Variadic<Index>:$strides,
I64ArrayAttr:$static_offsets,
I64ArrayAttr:$static_sizes,
I64ArrayAttr:$static_strides
DenseI64ArrayAttr:$static_offsets,
DenseI64ArrayAttr:$static_sizes,
DenseI64ArrayAttr:$static_strides
);
let results = (outs AnyRankedTensor:$result);

Expand Down Expand Up @@ -807,9 +807,9 @@ def Tensor_InsertSliceOp : Tensor_OpWithOffsetSizesAndStrides<"insert_slice", [
Variadic<Index>:$offsets,
Variadic<Index>:$sizes,
Variadic<Index>:$strides,
I64ArrayAttr:$static_offsets,
I64ArrayAttr:$static_sizes,
I64ArrayAttr:$static_strides
DenseI64ArrayAttr:$static_offsets,
DenseI64ArrayAttr:$static_sizes,
DenseI64ArrayAttr:$static_strides
);
let results = (outs AnyRankedTensor:$result);

Expand Down Expand Up @@ -1013,7 +1013,7 @@ def Tensor_ExpandShapeOp : Tensor_ReassociativeReshapeOp<"expand_shape"> {
rank whose sizes are a reassociation of the original `src`.

A reassociation is defined as a continuous grouping of dimensions and is
represented with an array of I64ArrayAttr attribute.
represented with an array of DenseI64ArrayAttr attribute.

The verification rule is that the reassociation maps are applied to the
result tensor with the higher rank to obtain the operand tensor with the
Expand Down Expand Up @@ -1065,7 +1065,7 @@ def Tensor_CollapseShapeOp : Tensor_ReassociativeReshapeOp<"collapse_shape"> {
rank whose sizes are a reassociation of the original `src`.

A reassociation is defined as a continuous grouping of dimensions and is
represented with an array of I64ArrayAttr attribute.
represented with an array of DenseI64ArrayAttr attribute.

The verification rule is that the reassociation maps are applied to the
operand tensor with the higher rank to obtain the result tensor with the
Expand Down Expand Up @@ -1206,8 +1206,8 @@ def Tensor_PadOp : Tensor_Op<"pad", [
AnyTensor:$source,
Variadic<Index>:$low,
Variadic<Index>:$high,
I64ArrayAttr:$static_low,
I64ArrayAttr:$static_high,
DenseI64ArrayAttr:$static_low,
DenseI64ArrayAttr:$static_high,
UnitAttr:$nofold);

let regions = (region SizedRegion<1>:$region);
Expand Down Expand Up @@ -1254,16 +1254,17 @@ def Tensor_PadOp : Tensor_Op<"pad", [

// Return a vector of all the static or dynamic values (low/high padding) of
// the op.
inline SmallVector<OpFoldResult> getMixedPadImpl(ArrayAttr staticAttrs,
inline SmallVector<OpFoldResult> getMixedPadImpl(ArrayRef<int64_t> staticAttrs,
ValueRange values) {
Builder builder(*this);
SmallVector<OpFoldResult> res;
unsigned numDynamic = 0;
unsigned count = staticAttrs.size();
for (unsigned idx = 0; idx < count; ++idx) {
if (ShapedType::isDynamic(staticAttrs[idx].cast<IntegerAttr>().getInt()))
if (ShapedType::isDynamic(staticAttrs[idx]))
res.push_back(values[numDynamic++]);
else
res.push_back(staticAttrs[idx]);
res.push_back(builder.getI64IntegerAttr(staticAttrs[idx]));
}
return res;
}
Expand Down Expand Up @@ -1400,9 +1401,9 @@ def Tensor_ParallelInsertSliceOp : Tensor_Op<"parallel_insert_slice", [
Variadic<Index>:$offsets,
Variadic<Index>:$sizes,
Variadic<Index>:$strides,
I64ArrayAttr:$static_offsets,
I64ArrayAttr:$static_sizes,
I64ArrayAttr:$static_strides
DenseI64ArrayAttr:$static_offsets,
DenseI64ArrayAttr:$static_sizes,
DenseI64ArrayAttr:$static_strides
);
let assemblyFormat = [{
$source `into` $dest ``
Expand Down Expand Up @@ -1748,7 +1749,7 @@ def Tensor_PackOp : Tensor_RelayoutOp<"pack", [
DefaultValuedOptionalAttr<DenseI64ArrayAttr, "{}">:$outer_dims_perm,
DenseI64ArrayAttr:$inner_dims_pos,
Variadic<Index>:$inner_tiles,
I64ArrayAttr:$static_inner_tiles);
DenseI64ArrayAttr:$static_inner_tiles);
let results = (outs AnyRankedTensor:$result);
let assemblyFormat = [{
$source
Expand Down Expand Up @@ -1803,7 +1804,7 @@ def Tensor_UnPackOp : Tensor_RelayoutOp<"unpack"> {
DefaultValuedOptionalAttr<DenseI64ArrayAttr, "{}">:$outer_dims_perm,
DenseI64ArrayAttr:$inner_dims_pos,
Variadic<Index>:$inner_tiles,
I64ArrayAttr:$static_inner_tiles);
DenseI64ArrayAttr:$static_inner_tiles);
let results = (outs AnyRankedTensor:$result);
let assemblyFormat = [{
$source
Expand Down
12 changes: 12 additions & 0 deletions mlir/include/mlir/Dialect/Utils/StaticValueUtils.h
Expand Up @@ -87,6 +87,18 @@ bool isEqualConstantIntOrValue(OpFoldResult ofr1, OpFoldResult ofr2);
SmallVector<Value> getAsValues(OpBuilder &b, Location loc,
ArrayRef<OpFoldResult> valueOrAttrVec);

/// Return a vector of OpFoldResults with the same size a staticValues, but all
/// elements for which ShapedType::isDynamic is true, will be replaced by
/// dynamicValues.
SmallVector<OpFoldResult> getMixedValues(ArrayRef<int64_t> staticValues,
ValueRange dynamicValues, Builder &b);

/// Decompose a vector of mixed static or dynamic values into the corresponding
/// pair of arrays. This is the inverse function of `getMixedValues`.
std::pair<ArrayAttr, SmallVector<Value>>
decomposeMixedValues(Builder &b,
const SmallVectorImpl<OpFoldResult> &mixedValues);

} // namespace mlir

#endif // MLIR_DIALECT_UTILS_STATICVALUEUTILS_H
19 changes: 4 additions & 15 deletions mlir/include/mlir/Interfaces/ViewLikeInterface.h
Expand Up @@ -21,18 +21,6 @@

namespace mlir {

/// Return a vector of OpFoldResults with the same size a staticValues, but all
/// elements for which ShapedType::isDynamic is true, will be replaced by
/// dynamicValues.
SmallVector<OpFoldResult, 4> getMixedValues(ArrayAttr staticValues,
ValueRange dynamicValues);

/// Decompose a vector of mixed static or dynamic values into the corresponding
/// pair of arrays. This is the inverse function of `getMixedValues`.
std::pair<ArrayAttr, SmallVector<Value>>
decomposeMixedValues(Builder &b,
const SmallVectorImpl<OpFoldResult> &mixedValues);

class OffsetSizeAndStrideOpInterface;

namespace detail {
Expand Down Expand Up @@ -61,7 +49,7 @@ namespace mlir {
/// idiomatic printing of mixed value and integer attributes in a list. E.g.
/// `[%arg0, 7, 42, %arg42]`.
void printDynamicIndexList(OpAsmPrinter &printer, Operation *op,
OperandRange values, ArrayAttr integers);
OperandRange values, ArrayRef<int64_t> integers);

/// Pasrer hook for custom directive in assemblyFormat.
///
Expand All @@ -79,13 +67,14 @@ void printDynamicIndexList(OpAsmPrinter &printer, Operation *op,
ParseResult
parseDynamicIndexList(OpAsmParser &parser,
SmallVectorImpl<OpAsmParser::UnresolvedOperand> &values,
ArrayAttr &integers);
DenseI64ArrayAttr &integers);

/// Verify that a the `values` has as many elements as the number of entries in
/// `attr` for which `isDynamic` evaluates to true.
LogicalResult verifyListOfOperandsOrIntegers(Operation *op, StringRef name,
unsigned expectedNumElements,
ArrayAttr attr, ValueRange values);
ArrayRef<int64_t> attr,
ValueRange values);

} // namespace mlir

Expand Down

0 comments on commit a9733b8

Please sign in to comment.