Problem Statement
The TilingInterface is designed to allow generating tiled implementations of operations. In addition to tiling specific interface methods for use within helpers like scf::tileUsingSCF, the interface includes a number of methods designed for “tile and fuse” algorithms, grouped below:
Tiling
getLoopIteratorTypesgetIterationDomaingetTiledImplementationgetResultTilePosition
Fusion
- Producer fusion
generateResultTileValuegetIterationDomainTileFromResultTile
- Consumer fusion
getTiledImplementationFromOperandTilegetIterationDomainTileFromOperandTile
This design works well for chains of tilable ops as users can in theory choose to tile any of the operators in the chain and fuse in the surrounding operations. The fact that fusion is tied to the TilingInterface, however, restricts the fusion algorithm to tilable ops.
Consider the following example
%0 = ...
%1 = linalg.transpose
%2 = tensor.extract_slice %1
%4 = linalg.transpose %2
Currently, trying to tile %4 and fuse producers would stop on %3 (a la tileConsumersAndFuseProducersUsingSCF) as tensor.extract_slice does not implement the tiling interface. Implementing the tiling interface should be unecessary to perform the fusion though, as after tiling the linalg.transpose we should expect something like the following:
%0 = ...
%1 = linalg.transpose
%2 = tensor.extract_slice %1
%3 = scf.for {
%4 = tensor.extract_slice %2
%5 = linalg.transpose %4
scf.yield %5
}
Where at this point we could merge consecutive extract slice ops and continue fusion on the merged extract slice, fusing in %1.
Similar reasoning applies to tensor.expand_shape and tensor.collapse_shape where we do not want to implement the tiling interface for those ops but do want to fuse them in situations like the above.
Proposed Solution
The solution proposed here is to split the TilingInterface into two interfaces: itself (TilingInterface) and one specifically for fusion, FusableOpInterface (naming suggestions welcome). The interface methods would be split into the two groups listed above (matching with the existing documentation in TilingInterface.td).
The TilingInterface can be changed to inherit from the FusableOpInterface, leaving existing TilingInterface implementations alone and avoiding API breakages.