Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[mlir][TilingInterface] Enabling tiling
tensor.pad
using `TilingInt…
…erface`. Update the implementation of `TilingInterface` for `tensor.pad` operations to allow tiling the op using the existing patterns for the interface. Verify that tests that pass with existing pad tiling patterns producer the same results through TilingInterface patterns. Reviewed By: antiagainst Differential Revision: https://reviews.llvm.org/D132720
- Loading branch information
Mahesh Ravishankar
committed
Aug 26, 2022
1 parent
e117137
commit a235562
Showing
6 changed files
with
172 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
140 changes: 140 additions & 0 deletions
140
mlir/test/Interfaces/TilingInterface/tile-pad-using-interface.mlir
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// RUN: mlir-opt -test-tiling-interface=tile-using-scf-for -resolve-shaped-type-result-dims -cse -split-input-file %s | FileCheck %s | ||
|
||
// 2D tiling of dynamic 2D pad tensor op. | ||
func.func @dynamic_2d_pad_tensor(%input_tensor: tensor<?x?xf32>, | ||
%pad_value: f32) -> tensor<?x?xf32> { | ||
%0 = tensor.pad %input_tensor low[3, 4] high[5, 3] { | ||
^bb0(%arg1: index, %arg2: index): | ||
tensor.yield %pad_value : f32 | ||
} {__internal_linalg_transform__ = "pad_2dtiling"}: tensor<?x?xf32> to tensor<?x?xf32> | ||
return %0 : tensor<?x?xf32> | ||
} | ||
// CHECK-DAG: #[[MAP0:.+]] = affine_map<()[s0] -> (s0 + 8)> | ||
// CHECK-DAG: #[[MAP1:.+]] = affine_map<()[s0] -> (s0 + 7)> | ||
// CHECK: func @dynamic_2d_pad_tensor( | ||
// CHECK-SAME: %[[IN:[a-zA-Z0-9]+]]: tensor<?x?xf32> | ||
// CHECK-DAG: %[[C0:.+]] = arith.constant 0 : index | ||
// CHECK-DAG: %[[C1:.+]] = arith.constant 1 : index | ||
// CHECK-DAG: %[[C2:.+]] = arith.constant 2 : index | ||
// CHECK-DAG: %[[C3:.+]] = arith.constant 3 : index | ||
// CHECK: %[[DIM_IN0:.+]] = tensor.dim %[[IN]], %[[C0]] | ||
// CHECK: %[[DIM0:.+]] = affine.apply #[[MAP0]]()[%[[DIM_IN0]]] | ||
// CHECK: %[[DIM_IN1:.+]] = tensor.dim %[[IN]], %[[C1]] | ||
// CHECK: %[[DIM1:.+]] = affine.apply #[[MAP1]]()[%[[DIM_IN1]]] | ||
// CHECK: %[[RESULT:[a-zA-Z0-9]+]] = scf.for %[[IV0:[a-zA-Z0-9]+]] = %[[C0]] to %[[DIM0]] step %[[C2]] | ||
// CHECK: scf.for {{.*}} = %[[C0]] to %[[DIM1]] step %[[C3]] iter_args(%[[INNER_OUT:.*]] = | ||
// CHECK: %[[SWAP_RESULT:.*]] = scf.if | ||
// CHECK: tensor.generate | ||
// CHECK: else | ||
// CHECK: %[[SLICE:.*]] = tensor.extract_slice %[[IN]][{{.*}}, {{.*}}] [{{.*}}, {{.*}}] [1, 1] | ||
// CHECK: %[[PAD:.*]] = tensor.pad %[[SLICE]] | ||
// CHECK: tensor.insert_slice %[[SWAP_RESULT]] into %[[INNER_OUT]][{{.*}}, {{.*}}] [{{.*}}, {{.*}}] [1, 1] | ||
// CHECK: return %[[RESULT]] | ||
|
||
// ----- | ||
|
||
func.func @dynamic_2d_pad_tensor_inner_tiling(%input_tensor: tensor<?x?xf32>, | ||
%pad_value: f32) -> tensor<?x?xf32> { | ||
%0 = tensor.pad %input_tensor low[3, 4] high[5, 3] { | ||
^bb0(%arg1: index, %arg2: index): | ||
tensor.yield %pad_value : f32 | ||
} {__internal_linalg_transform__ = "pad_inner_tiling"}: tensor<?x?xf32> to tensor<?x?xf32> | ||
return %0 : tensor<?x?xf32> | ||
} | ||
// CHECK-DAG: #[[MAP0:.*]] = affine_map<()[s0] -> (s0 + 8)> | ||
// CHECK-DAG: #[[MAP1:.*]] = affine_map<()[s0] -> (s0 + 7)> | ||
// CHECK: func @dynamic_2d_pad_tensor_inner_tiling( | ||
// CHECK-SAME: %[[IN:.*]]: tensor<?x?xf32> | ||
// CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index | ||
// CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index | ||
// CHECK-DAG: %[[C3:.*]] = arith.constant 3 : index | ||
// CHECK: %[[DIM_IN0:.*]] = tensor.dim %[[IN]], %[[C0]] | ||
// CHECK: %[[DIM0:.*]] = affine.apply #[[MAP0]]()[%[[DIM_IN0]]] | ||
// CHECK: %[[DIM_IN1:.*]] = tensor.dim %[[IN]], %[[C1]] | ||
// CHECK: %[[DIM1:.*]] = affine.apply #[[MAP1]]()[%[[DIM_IN1]]] | ||
// CHECK: %[[RESULT:.*]] = scf.for {{.*}} = %[[C0]] to %[[DIM1]] step %[[C3]] iter_args(%[[INNER_OUT:.*]] = | ||
// CHECK: %[[SWAP_RESULT:.*]] = scf.if | ||
// CHECK: tensor.generate | ||
// CHECK: else | ||
// CHECK: %[[SLICE:.*]] = tensor.extract_slice %[[IN]][{{.*}}, {{.*}}] [{{.*}}, {{.*}}] [1, 1] | ||
// CHECK: %[[PAD:.*]] = tensor.pad %[[SLICE]] low[3, %{{.*}}] high[{{.*}}, {{.*}}] | ||
// CHECK: tensor.insert_slice %[[SWAP_RESULT]] into %[[INNER_OUT]][%[[C0]], {{.*}}] [%[[DIM0]], {{.*}}] [1, 1] | ||
// CHECK: return %[[RESULT]] | ||
|
||
// ----- | ||
|
||
func.func @static_pad_tensor(%input_tensor: tensor<7x9xf32>, | ||
%pad_value: f32) -> tensor<15x16xf32> { | ||
%0 = tensor.pad %input_tensor low[3, 4] high[5, 3] { | ||
^bb0(%arg1: index, %arg2: index): | ||
tensor.yield %pad_value : f32 | ||
} {__internal_linalg_transform__ = "pad_2dtiling"} : tensor<7x9xf32> to tensor<15x16xf32> | ||
return %0 : tensor<15x16xf32> | ||
} | ||
// CHECK-LABEL: func @static_pad_tensor( | ||
// CHECK-SAME: %[[IN:.*]]: tensor<7x9xf32> | ||
// CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index | ||
// CHECK-DAG: %[[C2:.*]] = arith.constant 2 : index | ||
// CHECK-DAG: %[[C3:.*]] = arith.constant 3 : index | ||
// CHECK-DAG: %[[C15:.*]] = arith.constant 15 : index | ||
// CHECK-DAG: %[[C16:.*]] = arith.constant 16 : index | ||
// CHECK: %[[RESULT:.*]] = scf.for {{.*}} = %[[C0]] to %[[C15]] step %[[C2]] | ||
// CHECK: scf.for {{.*}} = %[[C0]] to %[[C16]] step %[[C3]] iter_args(%[[INNER_OUT:.*]] = | ||
// CHECK: %[[SWAP_RESULT:.*]] = scf.if | ||
// CHECK: tensor.generate | ||
// CHECK: else | ||
// CHECK: %[[SLICE:.*]] = tensor.extract_slice %[[IN]][{{.*}}, {{.*}}] [{{.*}}, {{.*}}] [1, 1] | ||
// CHECK: %[[PAD:.*]] = tensor.pad %[[SLICE]] | ||
// CHECK: tensor.insert_slice %[[SWAP_RESULT]] into %[[INNER_OUT]][{{.*}}, {{.*}}] [{{.*}}, {{.*}}] [1, 1] | ||
// CHECK: return %[[RESULT]] | ||
|
||
// ----- | ||
|
||
func.func @static_pad_tensor_inner_tiling(%input_tensor: tensor<7x9xf32>, | ||
%pad_value: f32) -> tensor<15x16xf32> { | ||
%0 = tensor.pad %input_tensor low[3, 4] high[5, 3] { | ||
^bb0(%arg1: index, %arg2: index): | ||
tensor.yield %pad_value : f32 | ||
} {__internal_linalg_transform__ = "pad_inner_tiling"} : tensor<7x9xf32> to tensor<15x16xf32> | ||
return %0 : tensor<15x16xf32> | ||
} | ||
// CHECK-LABEL: func @static_pad_tensor_inner_tiling( | ||
// CHECK-SAME: %[[IN:.*]]: tensor<7x9xf32> | ||
// CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index | ||
// CHECK-DAG: %[[C3:.*]] = arith.constant 3 : index | ||
// CHECK-DAG: %[[C15:.*]] = arith.constant 15 : index | ||
// CHECK-DAG: %[[C16:.*]] = arith.constant 16 : index | ||
// CHECK: %[[RESULT:.*]] = scf.for {{.*}} = %[[C0]] to %[[C16]] step %[[C3]] iter_args(%[[INNER_OUT:.*]] = | ||
// CHECK: %[[SWAP_RESULT:.*]] = scf.if | ||
// CHECK: tensor.generate | ||
// CHECK: else | ||
// CHECK: %[[SLICE:.*]] = tensor.extract_slice %[[IN]][0, {{.*}}] [7, {{.*}}] [1, 1] | ||
// CHECK: %[[PAD:.*]] = tensor.pad %[[SLICE]] low[3, %{{.*}}] high[5, {{.*}}] | ||
// CHECK: tensor.insert_slice %[[SWAP_RESULT]] into %[[INNER_OUT]][%[[C0]], {{.*}}] [%[[C15]], {{.*}}] [1, 1] | ||
// CHECK: return %[[RESULT]] | ||
|
||
/// Rest of the tests only check that they dont fail. | ||
|
||
// ----- | ||
|
||
func.func @dynamic_2d_pad_tensor_outer_tiling(%input_tensor: tensor<?x?xf32>, | ||
%pad_value: f32) -> tensor<?x?xf32> { | ||
%0 = tensor.pad %input_tensor low[3, 4] high[5, 3] { | ||
^bb0(%arg1: index, %arg2: index): | ||
tensor.yield %pad_value : f32 | ||
} {__internal_linalg_transform__ = "pad_outer_tiling"}: tensor<?x?xf32> to tensor<?x?xf32> | ||
return %0 : tensor<?x?xf32> | ||
} | ||
// CHECK-LABEL: func @dynamic_2d_pad_tensor_outer_tiling | ||
|
||
// ----- | ||
|
||
func.func @static_pad_tensor_outer_tiling(%input_tensor: tensor<7x9xf32>, | ||
%pad_value: f32) -> tensor<15x16xf32> { | ||
%0 = tensor.pad %input_tensor low[3, 4] high[5, 3] { | ||
^bb0(%arg1: index, %arg2: index): | ||
tensor.yield %pad_value : f32 | ||
} {__internal_linalg_transform__ = "pad_inner_tiling"} : tensor<7x9xf32> to tensor<15x16xf32> | ||
return %0 : tensor<15x16xf32> | ||
} | ||
// CHECK-LABEL: func @static_pad_tensor_outer_tiling |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters