This change adds an option to use a custom operation to generate the inter-tile loops during tiling. When the loop type is set to scf::SCFTilingOptions::LoopType::CustomOp, the method mlir::tileUsingSCF provides two callback functions First one to generate the header of the loop. Second one to generate the terminator of the loop. These methods receive the information needed to generate the loops/terminator and expect to return information needed to generate the code for the intra-tile computation. See comments for more details. Presently this is adds support only for tiling. Subsequent commits will update this to add support for fusion as well. The PR is split into two commits. The first commit is an NFC that just refactors the code (and cleans up some naming) to make it easier to add the support for custom loop operations. The second commit adds the support for using a custom loop operation, as well as a test to exercise this path. Note that this is duplicate of https://github.com/llvm/llvm-project/pull/159506 that was accidently committed and was reverted in https://github.com/llvm/llvm-project/pull/159598 to wait for reviews. Signed-off-by: MaheshRavishankar [mahesh.ravishankar@gmail.com](mailto:mahesh.ravishankar@gmail.com) --------- Signed-off-by: MaheshRavishankar <mahesh.ravishankar@gmail.com>
177 lines
7.3 KiB
TableGen
177 lines
7.3 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",
|
|
[AttrSizedOperandSegments,
|
|
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
|
|
Variadic<TransformHandleTypeInterface>:$targets,
|
|
Variadic<TransformHandleTypeInterface>:$loops,
|
|
DefaultValuedAttr<I32Attr, "1">:$num_consumer_to_fuse);
|
|
let results = (outs TransformHandleTypeInterface:$consumer,
|
|
TransformHandleTypeInterface:$fused_consumer);
|
|
|
|
let assemblyFormat = [{
|
|
$targets `in` `(` $loops `)`
|
|
(`num_consumer_to_fuse` `=` $num_consumer_to_fuse^)?
|
|
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)
|
|
}];
|
|
}
|
|
|
|
def TestTileAndFuseOuterParallelPartialReductionOp : Op<
|
|
Transform_Dialect, "test.tile_and_fuse_outer_parallel_partial_reduction",
|
|
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
|
|
DeclareOpInterfaceMethods<TransformOpInterface>,
|
|
ReportTrackingListenerFailuresOpTrait]> {
|
|
let description = [{
|
|
Test operation to tile an operation using partial reduction with
|
|
outer parallel strategy, and to fuse its producers.
|
|
}];
|
|
|
|
let arguments = (ins TransformHandleTypeInterface:$root_op,
|
|
DefaultValuedAttr<I64ArrayAttr, "{}">:$reduction_dims,
|
|
DefaultValuedAttr<I64ArrayAttr, "{}">:$tile_sizes,
|
|
OptionalAttr<DeviceMappingArrayAttr>:$mapping);
|
|
|
|
let results = (outs TransformHandleTypeInterface:$tiled_ops,
|
|
Variadic<TransformHandleTypeInterface>:$loops);
|
|
let assemblyFormat = [{
|
|
$root_op (`reduction_dims` `=` $reduction_dims^)?
|
|
(`tile_sizes` `=` $tile_sizes^)? (`mapping` `=` $mapping^)?
|
|
attr-dict `:` functional-type(operands, results)
|
|
}];
|
|
}
|
|
|
|
def TestTileUsingCustomLoopOp : Op<
|
|
Transform_Dialect, "test.tile_using_custom_loop",
|
|
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
|
|
DeclareOpInterfaceMethods<TransformOpInterface>,
|
|
ReportTrackingListenerFailuresOpTrait]> {
|
|
let description = [{
|
|
Test Transform op to tile an operation using custom loops.
|
|
|
|
The test just folds all the loops and into a single loop and then
|
|
delinearizes the indices.
|
|
}];
|
|
|
|
let arguments = (ins TransformHandleTypeInterface:$root_op,
|
|
DefaultValuedAttr<I64ArrayAttr, "{}">:$tile_sizes);
|
|
let results = (outs TransformHandleTypeInterface:$tiled_ops,
|
|
Variadic<TransformHandleTypeInterface>:$loops);
|
|
|
|
let assemblyFormat = [{
|
|
$root_op `tile_sizes` `=` $tile_sizes
|
|
attr-dict `:` functional-type(operands, results)
|
|
}];
|
|
}
|
|
|
|
#endif // TEST_TILINGINTERFACE_TRANSFORM_OPS
|