408 lines · plain
1// RUN: mlir-opt --transform-interpreter -canonicalize -split-input-file --verify-diagnostics %s | FileCheck %s2 3// CHECK-DAG: #[[$MAP0:.*]] = affine_map<(d0) -> (-d0 + 24, 5)>4// CHECK-DAG: #[[$MAP1:.*]] = affine_map<(d0) -> (-d0 + (d0 ceildiv 8) * 8)>5 6// CHECK-LABEL: pad_lhs7func.func @pad_lhs(8 %arg0: tensor<24x12xf32>, %arg1: tensor<12x25xf32>, %arg2: tensor<24x25xf32>)9 -> tensor<24x25xf32>10{11 // CHECK: scf.for %{{.*}} -> (tensor<24x25xf32>)12 // CHECK: %[[MIN:.*]] = affine.min #[[$MAP0]](%{{.*}})13 // CHECK: %[[H0:.*]] = affine.apply #[[$MAP1]](%[[MIN]])14 // CHECK: tensor.pad %{{.*}} low[0, 0] high[%[[H0]], 0]15 // CHECK: : tensor<?x12xf32> to tensor<?x12xf32>16 17 // CHECK: %[[H1:.*]] = affine.apply #[[$MAP1]](%[[MIN]])18 // CHECK: tensor.pad %{{.*}} low[0, 0] high[%[[H1]], 0]19 // CHECK: : tensor<?x25xf32> to tensor<?x25xf32>20 21 // CHECK: linalg.matmul ins(%{{.*}}, %{{.*}} : tensor<?x12xf32>, tensor<12x25xf32>) outs(%{{.*}} : tensor<?x25xf32>) -> tensor<?x25xf32>22 23 // CHECK: tensor.extract_slice %{{.*}}[0, 0] [%{{.*}}, 25] [1, 1]24 // CHECK: : tensor<?x25xf32> to tensor<?x25xf32>25 // CHECK: tensor.insert_slice %{{.*}} into %{{.*}}[%{{.*}}, 0] [%{{.*}}, 25] [1, 1]26 // CHECK-SAME: : tensor<?x25xf32> into tensor<24x25xf32>27 %0 = linalg.matmul ins(%arg0, %arg1 : tensor<24x12xf32>, tensor<12x25xf32>) outs(%arg2 : tensor<24x25xf32>) -> tensor<24x25xf32>28 func.return %0 : tensor<24x25xf32>29}30 31module attributes {transform.with_named_sequence} {32 transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {33 %matmul = transform.structured.match ops{["linalg.matmul"]} in %module_op34 : (!transform.any_op) -> !transform.any_op35 36 // Tile to 5 then pad to 8 (supposedly to better hit vector ops).37 %matmul_l1, %loops_l1 = transform.structured.tile_using_for %matmul tile_sizes [5] : (!transform.any_op) -> (!transform.any_op, !transform.any_op)38 %matmul_padded, %_ = transform.structured.pad_tiling_interface %matmul_l1 to padding_sizes [8] pad_to_multiple_of {39 padding_values=[0.0: f32, 0.0 : f32, 0.0 : f32]40 } : (!transform.any_op) -> (!transform.any_op, !transform.any_op)41 42 transform.yield43 }44}45 46// -----47 48#map = affine_map<(d0, d1, d2) -> (d0, d1)>49#map1 = affine_map<(d0, d1, d2) -> (d0, d2, d0 + d1)>50 51module {52 53// CHECK-LABEL: @generic54// CHECK-SAME: %[[T0:.*]]: tensor<7x5xf32>,55// CHECK-SAME: %[[T1:.*]]: tensor<7x11x11xf32>)56 func.func @generic(%arg0: tensor<7x5xf32>, %arg1: tensor<7x11x11xf32>) -> tensor<7x11x11xf32> {57 58 // CHECK-DAG: %[[CST:.*]] = arith.constant 0.59 60 // CHECK: %[[PAD0:.*]] = tensor.pad %[[T0]] low[0, 0] high[2, 0]61 // CHECK: : tensor<7x5xf32> to tensor<9x5xf32>62 // CHECK: %[[PAD1:.*]] = tensor.pad %[[T1]] low[0, 0, 0] high[2, 4, 2] {63 // CHECK: : tensor<7x11x11xf32> to tensor<9x15x13xf32>64 // CHECK-NEXT: linalg.generic65 // CHECK: tensor.extract_slice %{{.*}}[0, 0, 0] [7, 11, 11] [1, 1, 1] : tensor<9x15x13xf32> to tensor<7x11x11xf32>66 %0 = linalg.generic {indexing_maps = [#map, #map1], iterator_types = ["parallel", "parallel", "reduction"]} ins(%arg0 : tensor<7x5xf32>) outs(%arg1 : tensor<7x11x11xf32>) {67 ^bb0(%in: f32, %out: f32):68 linalg.yield %in : f3269 } -> tensor<7x11x11xf32>70 return %0 : tensor<7x11x11xf32>71 }72 module attributes {transform.with_named_sequence} {73 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {74 %0 = transform.structured.match ops{["linalg.generic"]} in %arg0 : (!transform.any_op) -> !transform.any_op75 %padded, %pad = transform.structured.pad_tiling_interface %0 to padding_sizes [3, 0, 5] pad_to_multiple_of {76 padding_values = [0.0 : f32, 0.0 : f32, 0.0 : f32]77 } : (!transform.any_op) -> (!transform.any_op, !transform.any_op)78 transform.yield79 }80 }81}82 83// -----84 85// CHECK-DAG: #[[$MAP0:.*]] = affine_map<()[s0, s1] -> (-s1 + (s0 ceildiv 3) * 3)>86// CHECK-DAG: #[[$MAP1:.*]] = affine_map<()[s0, s1] -> (-s1 + (s0 ceildiv 3) * 3 + 4)>87// CHECK-DAG: #[[$MAP2:.*]] = affine_map<()[s0] -> (s0 + 5)>88 89#map = affine_map<(d0, d1, d2) -> (d0, d1)>90#map1 = affine_map<(d0, d1, d2) -> (d0, d2, d0 + d1)>91module {92 93// CHECK-LABEL: @generic94// CHECK-SAME: %[[T0:.*]]: tensor<?x5xf32>,95// CHECK-SAME: %[[T1:.*]]: tensor<?x11x?xf32>)96 func.func @generic(%arg0: tensor<?x5xf32>, %arg1: tensor<?x11x?xf32>) -> tensor<?x11x?xf32> {97 98 // CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index99 // CHECK-DAG: %[[C2:.*]] = arith.constant 2 : index100 //101 // CHECK: %[[D0_0:.*]] = tensor.dim %{{.*}}, %[[C0]] : tensor<?x5xf32>102 // CHECK: %[[D0_1:.*]] = tensor.dim %{{.*}}, %[[C0]] : tensor<?x5xf32>103 // CHECK: %[[H0:.*]] = affine.apply #[[$MAP0]]()[%[[D0_0]], %[[D0_1]]]104 // CHECK: tensor.pad %{{.*}} low[0, 0] high[%[[H0]], 0] {105 // CHECK: : tensor<?x5xf32> to tensor<?x5xf32>106 //107 // CHECK: %[[D0_2:.*]] = tensor.dim %{{.*}}, %[[C0]] : tensor<?x11x?xf32>108 // CHECK: %[[H1:.*]] = affine.apply #[[$MAP0]]()[%[[D0_0]], %[[D0_2]]]109 // CHECK: %[[D2_0:.*]] = tensor.dim %{{.*}}, %[[C2]] : tensor<?x11x?xf32>110 // CHECK: %[[H2:.*]] = affine.apply #[[$MAP1]]()[%[[D0_0]], %[[D2_0]]]111 // CHECK: tensor.pad %{{.*}} low[0, 0, 0] high[%[[H1]], 4, %[[H2]]] {112 // CHECK: : tensor<?x11x?xf32> to tensor<?x15x?xf32>113 //114 // CHECK: %[[D0_3:.*]] = tensor.dim %{{.*}}, %[[C0]] : tensor<?x5xf32>115 // CHECK: %[[D2_1:.*]] = affine.apply #[[$MAP2]]()[%[[D0_3]]]116 // CHECK: linalg.generic {{.*}} ins(%{{.*}} : tensor<?x5xf32>) outs(%{{.*}} : tensor<?x15x?xf32>) {117 // CHECK: } -> tensor<?x15x?xf32>118 // CHECK: tensor.extract_slice %{{.*}}[0, 0, 0] [%[[D0_3]], 11, %[[D2_1]]] [1, 1, 1] : tensor<?x15x?xf32> to tensor<?x11x?xf32>119 //120 %0 = linalg.generic {indexing_maps = [#map, #map1], iterator_types = ["parallel", "parallel", "reduction"]} ins(%arg0 : tensor<?x5xf32>) outs(%arg1 : tensor<?x11x?xf32>) {121 ^bb0(%in: f32, %out: f32):122 linalg.yield %in : f32123 } -> tensor<?x11x?xf32>124 return %0 : tensor<?x11x?xf32>125 }126 module attributes {transform.with_named_sequence} {127 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {128 %0 = transform.structured.match ops{["linalg.generic"]} in %arg0 : (!transform.any_op) -> !transform.any_op129 %padded, %pad = transform.structured.pad_tiling_interface %0 to padding_sizes [3, 0, 5] pad_to_multiple_of {130 padding_values = [0.0 : f32, 0.0 : f32, 0.0 : f32]131 } : (!transform.any_op) -> (!transform.any_op, !transform.any_op)132 transform.yield133 }134 }135}136 137// -----138 139// CHECK-DAG: #[[$MAP0:.*]] = affine_map<()[s0] -> (-s0 + (s0 ceildiv 16) * 16)>140// CHECK-DAG: #[[$MAP1:.*]] = affine_map<()[s0, s1] -> (-s1 + (s0 ceildiv 16) * 16)>141// CHECK-DAG: #[[$MAP2:.*]] = affine_map<()[s0] -> ((s0 ceildiv 16) * 16)>142// CHECK-LABEL: pad_lhs143func.func @pad_lhs(144 %arg0: tensor<24x?xf32>, %arg1: tensor<?x25xf32>, %arg2: tensor<24x25xf32>)145 -> tensor<24x25xf32>146{147 // CHECK: %[[D0_0:.*]] = tensor.dim148 // CHECK: %[[H0:.*]] = affine.apply #[[$MAP0]]()[%[[D0_0]]]149 // CHECK: tensor.pad %{{.*}} low[0, 0] high[0, %[[H0]]]150 // CHECK: : tensor<24x?xf32> to tensor<24x?xf32>151 152 // CHECK: %[[D0_2:.*]] = tensor.dim153 // CHECK: %[[H1:.*]] = affine.apply #[[$MAP1]]()[%[[D0_0]], %[[D0_2]]]154 // CHECK: tensor.pad %{{.*}} low[0, 0] high[%[[H1]], 0]155 // CHECK: : tensor<?x25xf32> to tensor<?x25xf32>156 // CHECK: scf.for %{{.*}} -> (tensor<24x25xf32>)157 158 // CHECK: linalg.matmul ins(%{{.*}}, %{{.*}}: tensor<8x16xf32>, tensor<16x25xf32>) outs(%{{.*}} : tensor<8x25xf32>) -> tensor<8x25xf32>159 160 // CHECK: tensor.insert_slice %{{.*}} into %{{.*}}[%{{.*}}, 0] [8, 25] [1, 1]161 // CHECK-SAME: : tensor<8x25xf32> into tensor<24x25xf32>162 %0 = linalg.matmul ins(%arg0, %arg1 : tensor<24x?xf32>, tensor<?x25xf32>) outs(%arg2 : tensor<24x25xf32>) -> tensor<24x25xf32>163 func.return %0 : tensor<24x25xf32>164}165 166module attributes {transform.with_named_sequence} {167 transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {168 %matmul = transform.structured.match ops{["linalg.matmul"]} in %module_op169 : (!transform.any_op) -> !transform.any_op170 171 // Pad then tile should produce static shapes.172 %matmul_padded, %_ = transform.structured.pad_tiling_interface %matmul to padding_sizes [8, 0, 16] pad_to_multiple_of {173 padding_values=[0.0: f32, 0.0 : f32, 0.0 : f32]174 } : (!transform.any_op) -> (!transform.any_op, !transform.any_op)175 176 %m, %l0, %l1 = transform.structured.tile_using_for %matmul_padded tile_sizes [8, 0, 16]177 : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op)178 179 %func = transform.structured.match ops{["func.func"]} in %module_op180 : (!transform.any_op) -> !transform.any_op181 %func2 = transform.apply_registered_pass "resolve-shaped-type-result-dims" to %func182 : (!transform.any_op) -> !transform.any_op183 transform.apply_patterns to %func2 {184 transform.apply_patterns.canonicalization185 } {apply_cse} : !transform.any_op186 %minmax = transform.structured.match ops{["affine.min", "affine.max"]} in %module_op187 : (!transform.any_op) -> !transform.any_op188 transform.affine.simplify_min_max_affine_ops %minmax : !transform.any_op189 transform.apply_patterns to %func2 {190 transform.apply_patterns.canonicalization191 } {apply_cse} : !transform.any_op192 transform.yield193 }194}195 196// -----197 198// CHECK-DAG: #[[$MAP0:.*]] = affine_map<(d0)[s0] -> (-d0 + s0, 16)>199// CHECK-DAG: #[[$MAP1:.*]] = affine_map<(d0) -> (-d0 + 16)>200 201// CHECK-LABEL: pad_lhs202func.func @pad_lhs(203 %arg0: tensor<24x?xf32>, %arg1: tensor<?x25xf32>, %arg2: tensor<24x25xf32>)204 -> tensor<24x25xf32>205{206 // CHECK: scf.for %{{.*}} -> (tensor<24x25xf32>)207 // CHECK: %[[MIN:.*]] = affine.min #[[$MAP0]](%{{.*}})208 // CHECK: %[[H0:.*]] = affine.apply #[[$MAP1]](%[[MIN]])209 // CHECK: tensor.pad %{{.*}} low[0, 0] high[0, %[[H0]]]210 // CHECK: : tensor<8x?xf32> to tensor<8x16xf32>211 212 // CHECK: %[[H1:.*]] = affine.apply #[[$MAP1]](%[[MIN]])213 // CHECK: tensor.pad %{{.*}} low[0, 0] high[%[[H1]], 0]214 // CHECK: : tensor<?x25xf32> to tensor<16x25xf32>215 216 // CHECK: linalg.matmul ins(%{{.*}}, %{{.*}} : tensor<8x16xf32>, tensor<16x25xf32>) outs(%{{.*}} : tensor<8x25xf32>) -> tensor<8x25xf32>217 218 // CHECK: tensor.insert_slice %{{.*}} into %{{.*}}[%{{.*}}, 0] [8, 25] [1, 1]219 // CHECK-SAME: : tensor<8x25xf32> into tensor<24x25xf32>220 %0 = linalg.matmul ins(%arg0, %arg1 : tensor<24x?xf32>, tensor<?x25xf32>) outs(%arg2 : tensor<24x25xf32>) -> tensor<24x25xf32>221 func.return %0 : tensor<24x25xf32>222}223 224module attributes {transform.with_named_sequence} {225 transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {226 %matmul = transform.structured.match ops{["linalg.matmul"]} in %module_op227 : (!transform.any_op) -> !transform.any_op228 229 // Tile then pad should produce static shapes.230 %m, %l0, %l1 = transform.structured.tile_using_for %matmul tile_sizes [8, 0, 16]231 : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op)232 233 %matmul_padded, %_ = transform.structured.pad_tiling_interface %m to padding_sizes [8, 0, 16] pad_to_multiple_of {234 padding_values=[0.0: f32, 0.0 : f32, 0.0 : f32]235 } : (!transform.any_op) -> (!transform.any_op, !transform.any_op)236 237 transform.yield238 }239}240 241// -----242 243// CHECK-DAG: #[[$MAP0:.*]] = affine_map<(d0) -> (-d0 + 20, 8)>244// CHECK-DAG: #[[$MAP1:.*]] = affine_map<(d0)[s0] -> (-d0 + s0, 16)>245// CHECK-DAG: #[[$MAP2:.*]] = affine_map<(d0) -> (-d0 + 8)>246// CHECK-DAG: #[[$MAP3:.*]] = affine_map<(d0) -> (-d0 + 16)>247 248// CHECK-LABEL: pad_lhs249func.func @pad_lhs(250 %arg0: tensor<20x?xf32>, %arg1: tensor<?x25xf32>, %arg2: tensor<20x25xf32>)251 -> tensor<20x25xf32>252{253 // CHECK: linalg.matmul ins(%{{.*}}, %{{.*}} : tensor<8x16xf32>, tensor<16x25xf32>) outs(%{{.*}} : tensor<8x25xf32>) -> tensor<8x25xf32>254 %0 = linalg.matmul ins(%arg0, %arg1 : tensor<20x?xf32>, tensor<?x25xf32>) outs(%arg2 : tensor<20x25xf32>) -> tensor<20x25xf32>255 func.return %0 : tensor<20x25xf32>256}257 258module attributes {transform.with_named_sequence} {259 transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {260 %matmul = transform.structured.match ops{["linalg.matmul"]} in %module_op261 : (!transform.any_op) -> !transform.any_op262 263 // Tile then pad should produce static shapes.264 %m, %l0, %l1 = transform.structured.tile_using_for %matmul tile_sizes [8, 0, 16]265 : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op)266 267 %matmul_padded, %_ = transform.structured.pad_tiling_interface %m to padding_sizes [8, 0, 16] pad_to_multiple_of {268 padding_values=[0.0: f32, 0.0 : f32, 0.0 : f32]269 } : (!transform.any_op) -> (!transform.any_op, !transform.any_op)270 271 transform.yield272 }273}274 275// -----276 277// CHECK-LABEL: pad_conv278func.func @pad_conv(%arg0: tensor<1x16x16x4xf32>, %arg1: tensor<16x3x3x4xf32>, %arg2: tensor<1x14x14x16xf32>) -> tensor<1x14x14x16xf32> {279 280 // CHECK: tensor.pad %{{.*}} low[0, 0, 0, 0] high[0, 0, 2, 12]281 // CHECK: : tensor<1x16x16x4xf32> to tensor<1x16x18x16xf32>282 // CHECK: tensor.pad %{{.*}} low[0, 0, 0, 0] high[0, 0, 0, 12]283 // CHECK: : tensor<16x3x3x4xf32> to tensor<16x3x3x16xf32>284 // CHECK: tensor.pad %{{.*}} low[0, 0, 0, 0] high[0, 0, 2, 0]285 // CHECK: : tensor<1x14x14x16xf32> to tensor<1x14x16x16xf32>286 // CHECK-NEXT: linalg.conv_2d_nhwc_fhwc287 // CHECK: tensor.extract_slice %{{.*}}[0, 0, 0, 0] [1, 14, 14, 16] [1, 1, 1, 1] : tensor<1x14x16x16xf32> to tensor<1x14x14x16xf32>288 289 %0 = linalg.conv_2d_nhwc_fhwc290 {dilations = dense<1> : tensor<2xi64>, strides = dense<1> : tensor<2xi64> }291 ins(%arg0, %arg1: tensor<1x16x16x4xf32>, tensor<16x3x3x4xf32>)292 outs(%arg2: tensor<1x14x14x16xf32>) -> tensor<1x14x14x16xf32>293 return %0 : tensor<1x14x14x16xf32>294}295 296module attributes {transform.with_named_sequence} {297 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {298 %0 = transform.structured.match ops{["linalg.conv_2d_nhwc_fhwc"]} in %arg1 : (!transform.any_op) -> !transform.any_op299 %padded, %pad = transform.structured.pad_tiling_interface %0 to padding_sizes [0, 0, 16, 0, 0, 0, 16] pad_to_multiple_of {300 padding_values = [0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32]301 } : (!transform.any_op) -> (!transform.any_op, !transform.any_op)302 transform.yield303 }304}305 306// -----307 308// CHECK-DAG: #[[$MAP0:.*]] = affine_map<()[s0, s1] -> (-s1 + (s0 ceildiv 16) * 16 + 2)>309// CHECK-DAG: #[[$MAP1:.*]] = affine_map<()[s0, s1] -> (-s1 + (s0 ceildiv 16) * 16)>310 311// CHECK-LABEL: pad_conv_dynamic312func.func @pad_conv_dynamic(%arg0: tensor<1x16x?x4xf32>, %arg1: tensor<16x3x3x4xf32>, %arg2: tensor<1x14x?x16xf32>) -> tensor<1x14x?x16xf32> {313 314 // CHECK-DAG: %[[C2:.*]] = arith.constant 2 : index315 // CHECK: %[[D0_0:.*]] = tensor.dim %{{.*}}, %[[C2]] : tensor<1x14x?x16xf32>316 // CHECK: %[[D0_1:.*]] = tensor.dim %{{.*}}, %[[C2]] : tensor<1x16x?x4xf32>317 // CHECK: %[[H0:.*]] = affine.apply #[[$MAP0]]()[%[[D0_0]], %[[D0_1]]]318 // CHECK: tensor.pad %{{.*}} low[0, 0, 0, 0] high[0, 0, %[[H0]], 12]319 // CHECK: : tensor<1x16x?x4xf32> to tensor<1x16x?x16xf32>320 // CHECK: tensor.pad %{{.*}} low[0, 0, 0, 0] high[0, 0, 0, 12]321 // CHECK: : tensor<16x3x3x4xf32> to tensor<16x3x3x16xf32>322 // CHECK: %[[D1_0:.*]] = tensor.dim %{{.*}}, %[[C2]] : tensor<1x14x?x16xf32>323 // CHECK: %[[H1:.*]] = affine.apply #[[$MAP1]]()[%[[D0_0]], %[[D1_0]]]324 // CHECK: tensor.pad %{{.*}} low[0, 0, 0, 0] high[0, 0, %[[H1]], 0]325 // CHECK: : tensor<1x14x?x16xf32> to tensor<1x14x?x16xf32>326 // CHECK: %[[D2_0:.*]] = tensor.dim %{{.*}}, %[[C2]] : tensor<1x14x?x16xf32>327 // CHECK-NEXT: linalg.conv_2d_nhwc_fhwc328 // CHECK: tensor.extract_slice %{{.*}}[0, 0, 0, 0] [1, 14, %[[D2_0]], 16] [1, 1, 1, 1] : tensor<1x14x?x16xf32> to tensor<1x14x?x16xf32>329 330 %0 = linalg.conv_2d_nhwc_fhwc331 {dilations = dense<1> : tensor<2xi64>, strides = dense<1> : tensor<2xi64> }332 ins(%arg0, %arg1: tensor<1x16x?x4xf32>, tensor<16x3x3x4xf32>)333 outs(%arg2: tensor<1x14x?x16xf32>) -> tensor<1x14x?x16xf32>334 return %0 : tensor<1x14x?x16xf32>335}336 337module attributes {transform.with_named_sequence} {338 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {339 %0 = transform.structured.match ops{["linalg.conv_2d_nhwc_fhwc"]} in %arg1 : (!transform.any_op) -> !transform.any_op340 %padded, %pad = transform.structured.pad_tiling_interface %0 to padding_sizes [0, 0, 16, 0, 0, 0, 16] pad_to_multiple_of {341 padding_values = [0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32]342 } : (!transform.any_op) -> (!transform.any_op, !transform.any_op)343 transform.yield344 }345}346 347// -----348 349// CHECK-LABEL: pad_conv_strided350func.func @pad_conv_strided(%arg0: tensor<1x42x42x4xf32>, %arg1: tensor<16x3x3x4xf32>, %arg2: tensor<1x14x14x16xf32>) -> tensor<1x14x14x16xf32> {351 352 // CHECK: tensor.pad %{{.*}} low[0, 0, 0, 0] high[0, 0, 6, 12]353 // CHECK: : tensor<1x42x42x4xf32> to tensor<1x42x48x16xf32>354 // CHECK: tensor.pad %{{.*}} low[0, 0, 0, 0] high[0, 0, 0, 12]355 // CHECK: : tensor<16x3x3x4xf32> to tensor<16x3x3x16xf32>356 // CHECK: tensor.pad %{{.*}} low[0, 0, 0, 0] high[0, 0, 2, 0]357 // CHECK: : tensor<1x14x14x16xf32> to tensor<1x14x16x16xf32>358 // CHECK-NEXT: linalg.conv_2d_nhwc_fhwc359 // CHECK: tensor.extract_slice %{{.*}}[0, 0, 0, 0] [1, 14, 14, 16] [1, 1, 1, 1] : tensor<1x14x16x16xf32> to tensor<1x14x14x16xf32>360 361 %0 = linalg.conv_2d_nhwc_fhwc362 {dilations = dense<1> : tensor<2xi64>, strides = dense<3> : tensor<2xi64> }363 ins(%arg0, %arg1: tensor<1x42x42x4xf32>, tensor<16x3x3x4xf32>)364 outs(%arg2: tensor<1x14x14x16xf32>) -> tensor<1x14x14x16xf32>365 return %0 : tensor<1x14x14x16xf32>366}367 368module attributes {transform.with_named_sequence} {369 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {370 %0 = transform.structured.match ops{["linalg.conv_2d_nhwc_fhwc"]} in %arg1 : (!transform.any_op) -> !transform.any_op371 %padded, %pad = transform.structured.pad_tiling_interface %0 to padding_sizes [0, 0, 16, 0, 0, 0, 16] pad_to_multiple_of {372 padding_values = [0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32]373 } : (!transform.any_op) -> (!transform.any_op, !transform.any_op)374 transform.yield375 }376}377 378// -----379 380// CHECK-LABEL: pad_conv_dilated381func.func @pad_conv_dilated(%arg0: tensor<1x18x18x4xf32>, %arg1: tensor<16x3x3x4xf32>, %arg2: tensor<1x14x14x16xf32>) -> tensor<1x14x14x16xf32> {382 383 // CHECK: tensor.pad %{{.*}} low[0, 0, 0, 0] high[0, 0, 2, 12]384 // CHECK: : tensor<1x18x18x4xf32> to tensor<1x18x20x16xf32>385 // CHECK: tensor.pad %{{.*}} low[0, 0, 0, 0] high[0, 0, 0, 12]386 // CHECK: : tensor<16x3x3x4xf32> to tensor<16x3x3x16xf32>387 // CHECK: tensor.pad %{{.*}} low[0, 0, 0, 0] high[0, 0, 2, 0]388 // CHECK: : tensor<1x14x14x16xf32> to tensor<1x14x16x16xf32>389 // CHECK-NEXT: linalg.conv_2d_nhwc_fhwc390 // CHECK: tensor.extract_slice %{{.*}}[0, 0, 0, 0] [1, 14, 14, 16] [1, 1, 1, 1] : tensor<1x14x16x16xf32> to tensor<1x14x14x16xf32>391 392 %0 = linalg.conv_2d_nhwc_fhwc393 {dilations = dense<2> : tensor<2xi64>, strides = dense<1> : tensor<2xi64> }394 ins(%arg0, %arg1: tensor<1x18x18x4xf32>, tensor<16x3x3x4xf32>)395 outs(%arg2: tensor<1x14x14x16xf32>) -> tensor<1x14x14x16xf32>396 return %0 : tensor<1x14x14x16xf32>397}398 399module attributes {transform.with_named_sequence} {400 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) {401 %0 = transform.structured.match ops{["linalg.conv_2d_nhwc_fhwc"]} in %arg1 : (!transform.any_op) -> !transform.any_op402 %padded, %pad = transform.structured.pad_tiling_interface %0 to padding_sizes [0, 0, 16, 0, 0, 0, 16] pad_to_multiple_of {403 padding_values = [0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32, 0.0 : f32]404 } : (!transform.any_op) -> (!transform.any_op, !transform.any_op)405 transform.yield406 }407}408