This commit adds an API (`tileAndFuseConsumerOfSlice`) to fuse consumer to a producer within scf.for/scf.forall loop. To support this two new methods are added to the `TilingInterface` - `getIterationDomainTileFromOperandTile` - `getTiledImplementationFromOperandTile`. Consumer operations that implement this method can be used to be fused with tiled producer operands in a manner similar to (but essentially the inverse of) the fusion of an untiled producer with a tiled consumer. Note that this only does one `tiled producer` -> `consumer` fusion. This could be called repeatedly for fusing multiple consumers. The current implementation also is conservative in when this kicks in (like single use of the value returned by the inter-tile loops that surround the tiled producer, etc.) These can be relaxed over time. Signed-off-by: Abhishek Varma <abhvarma@amd.com> --------- Signed-off-by: Abhishek Varma <abhvarma@amd.com> Signed-off-by: Abhishek Varma <avarma094@gmail.com> Co-authored-by: cxy <chenxunyu1993@gmail.com>
125 lines
5.2 KiB
TableGen
125 lines
5.2 KiB
TableGen
//===- TestTilingInterfaceTransformOps.td -----------------*- tablegen -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef TEST_TILINGINTERFACE_TRANSFORM_OPS
|
|
#define TEST_TILINGINTERFACE_TRANSFORM_OPS
|
|
|
|
include "mlir/Dialect/SCF/IR/DeviceMappingInterface.td"
|
|
include "mlir/Dialect/Transform/IR/TransformDialect.td"
|
|
include "mlir/Dialect/Transform/Interfaces/TransformInterfaces.td"
|
|
include "mlir/Dialect/Transform/IR/TransformTypes.td"
|
|
include "mlir/Interfaces/SideEffectInterfaces.td"
|
|
include "mlir/IR/OpBase.td"
|
|
|
|
// Those operations in this file are meant for testing the tiling interface
|
|
// transformations using scf operations. Over time these testing options
|
|
// might be useful transformations in their own right. Move these over
|
|
// as transform ops in the main repo (also find a proper place for them)
|
|
|
|
def TestFuseAndYieldOp : Op<Transform_Dialect, "test.fuse_and_yield",
|
|
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
|
|
DeclareOpInterfaceMethods<TransformOpInterface>,
|
|
ReportTrackingListenerFailuresOpTrait]> {
|
|
let description = [{
|
|
Tiles the operations pointed to by the target handle, fuses their
|
|
producers greedily using the options provided as attributes.
|
|
It also yields some of the fused producers for testing.
|
|
|
|
On success returns the tiled operations as well as generated loops. Emits
|
|
a definite failure if tiling fails.
|
|
}];
|
|
|
|
let arguments =
|
|
(ins TransformHandleTypeInterface:$target,
|
|
DefaultValuedAttr<I64ArrayAttr, "{}">:$tile_sizes,
|
|
DefaultValuedAttr<I64ArrayAttr, "{}">:$tile_interchange,
|
|
DefaultValuedAttr<BoolAttr, "false">:$use_forall);
|
|
let results = (outs TransformHandleTypeInterface:$transfomed,
|
|
Variadic<TransformHandleTypeInterface>:$loops);
|
|
|
|
let assemblyFormat = [{
|
|
$target ($tile_sizes^)? (`interchange` $tile_interchange^)?
|
|
(`use_forall` $use_forall^)? attr-dict
|
|
`:` functional-type(operands, results)
|
|
}];
|
|
}
|
|
|
|
def TestFuseConsumerOp : Op<Transform_Dialect, "test.fuse_consumer",
|
|
[DeclareOpInterfaceMethods<TransformOpInterface>,
|
|
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
|
|
ReportTrackingListenerFailuresOpTrait]> {
|
|
let description = [{
|
|
Fuses the consumer of the operation pointed to by the target handle
|
|
using the options provided as attributes.
|
|
}];
|
|
|
|
let arguments =
|
|
(ins TransformHandleTypeInterface:$target);
|
|
let results = (outs TransformHandleTypeInterface:$consumer,
|
|
TransformHandleTypeInterface:$fused_consumer);
|
|
|
|
let assemblyFormat = [{
|
|
$target attr-dict `:` functional-type(operands, results)
|
|
}];
|
|
}
|
|
|
|
def TestTileUsingForallOp : Op<Transform_Dialect, "test.tile_using_forall",
|
|
[DeclareOpInterfaceMethods<TransformOpInterface>,
|
|
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
|
|
ReportTrackingListenerFailuresOpTrait]> {
|
|
let description = [{
|
|
Test operation use to test tiling using TilingInterface and scf.forall for
|
|
the loop constructs. This is similar to
|
|
`transform.structured.tile_using_for`. Use of this operation is an
|
|
intermediate state and will be replaced in due course with either
|
|
`transform.structured.tile_using_for` or
|
|
`transform.structured.tile_using_forall`.
|
|
|
|
On success returns the tiled operations as well as generated loops. Emits
|
|
a definite failure if tiling fails.
|
|
}];
|
|
|
|
let arguments = (ins TransformHandleTypeInterface:$target,
|
|
DefaultValuedAttr<I64ArrayAttr, "{}">:$tile_sizes,
|
|
DefaultValuedOptionalAttr<I64ArrayAttr, "{}">:$interchange,
|
|
OptionalAttr<DeviceMappingArrayAttr>:$mapping);
|
|
let results = (outs TransformHandleTypeInterface:$tiled_op,
|
|
Variadic<TransformHandleTypeInterface>:$loops);
|
|
|
|
let assemblyFormat = [{
|
|
$target ($tile_sizes^)? (`interchange` `=` $interchange^)?
|
|
(`mapping` `=` $mapping^)?
|
|
attr-dict `:` functional-type(operands, results)
|
|
}];
|
|
}
|
|
|
|
def TestFuseUsingForallOp : Op<Transform_Dialect, "test.fuse_using_forall",
|
|
[DeclareOpInterfaceMethods<TransformOpInterface>,
|
|
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
|
|
ReportTrackingListenerFailuresOpTrait]> {
|
|
let description = [{
|
|
Test operation to tile the operation pointed to by the target handle and
|
|
fuses their producers greedily using the options provided as attributes.
|
|
This operation uses scf.forall for the loop construct.
|
|
}];
|
|
let arguments = (ins TransformHandleTypeInterface:$root_op,
|
|
DefaultValuedAttr<I64ArrayAttr, "{}">:$tile_sizes,
|
|
DefaultValuedOptionalAttr<I64ArrayAttr, "{}">:$interchange,
|
|
OptionalAttr<DeviceMappingArrayAttr>:$mapping);
|
|
let results = (outs TransformHandleTypeInterface:$tiled_ops,
|
|
Variadic<TransformHandleTypeInterface>:$loops);
|
|
|
|
let assemblyFormat = [{
|
|
$root_op ($tile_sizes^)? (`interchange` $interchange^)?
|
|
(`mapping` `=` $mapping^)?
|
|
attr-dict `:` functional-type(operands, results)
|
|
}];
|
|
}
|
|
|
|
#endif // TEST_TILINGINTERFACE_TRANSFORM_OPS
|