brintos

brintos / llvm-project-archived public Read only

0
0
Text · 35.7 KiB · 9e7681d Raw
718 lines · plain
1// RUN: mlir-opt %s -transform-interpreter -cse -verify-diagnostics -split-input-file | FileCheck %s2 3  // CHECK-LABEL: func.func @pack(4func.func @pack(%arg0: tensor<129x47x16x16xf32>, %arg1: tensor<17x2x16x16x32x8xf32>) -> tensor<17x2x16x16x32x8xf32> {5  %cst_0 = arith.constant 0.0 : f326 7  // linalg.pack is lowered to tensor.pad + tensor.expand_shape + linalg.transpose8  //      CHECK: tensor.pad {{.*}} low[0, 0, 0, 0]9  //      CHECK:   : tensor<129x47x16x16xf32> to tensor<136x64x16x16xf32>10  //      CHECK: tensor.expand_shape %{{.*}} [{{.*}}[0, 1], [2, 3], [4], [5]]11  // CHECK-SAME:   : tensor<136x64x16x16xf32> into tensor<17x8x2x32x16x16xf32>12  //      CHECK: linalg.transpose13  // CHECK-SAME:   ins(%{{.*}} : tensor<17x8x2x32x16x16xf32>)14  // CHECK-SAME:   outs(%{{.*}} : tensor<17x2x16x16x32x8xf32>)15  // CHECK-SAME:   permutation = [0, 2, 4, 5, 3, 1]16  %pack = linalg.pack %arg0 padding_value(%cst_0 : f32) inner_dims_pos = [1, 0] inner_tiles = [32, 8] into %arg117    : tensor<129x47x16x16xf32> -> tensor<17x2x16x16x32x8xf32>18  return %pack : tensor<17x2x16x16x32x8xf32>19}20 21module attributes {transform.with_named_sequence} {22  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {23    %pack = transform.structured.match ops{["linalg.pack"]} in %module_op24      : (!transform.any_op) -> !transform.op<"linalg.pack">25    transform.structured.lower_pack %pack : (!transform.op<"linalg.pack">)26      -> (!transform.op<"tensor.pad">, !transform.op<"tensor.expand_shape">, !transform.op<"linalg.transpose">)27      transform.yield28  }29}30 31// -----32 33  // CHECK-LABEL: func.func @pack(34func.func @pack(%arg0: tensor<128x8xf32>, %arg1: tensor<8x8x16x1xf32>) -> tensor<8x8x16x1xf32> {35 36  // linalg.pack is lowered to tensor.pad + tensor.expand_shape + linalg.transpose37  //      CHECK: tensor.pad {{.*}} low[0, 0]38  //      CHECK:   : tensor<128x8xf32> to tensor<128x8xf32>39  //      CHECK: tensor.expand_shape %{{.*}} [{{.*}}[0, 1], [2, 3]]40  // CHECK-SAME:   : tensor<128x8xf32> into tensor<8x16x8x1xf32>41  //      CHECK: linalg.transpose42  // CHECK-SAME:   ins(%{{.*}} : tensor<8x16x8x1xf32>)43  // CHECK-SAME:   outs(%{{.*}} : tensor<8x8x16x1xf32>)44  // CHECK-SAME:   permutation = [0, 2, 1, 3]45 46  %pack = linalg.pack %arg0 inner_dims_pos = [0, 1] inner_tiles = [16, 1] into %arg147    : tensor<128x8xf32> -> tensor<8x8x16x1xf32>48 49  return %pack : tensor<8x8x16x1xf32>50}51 52module attributes {transform.with_named_sequence} {53  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {54    %pack = transform.structured.match ops{["linalg.pack"]} in %module_op55      : (!transform.any_op) -> !transform.op<"linalg.pack">56    transform.structured.lower_pack %pack : (!transform.op<"linalg.pack">)57      -> (!transform.op<"tensor.pad">, !transform.op<"tensor.expand_shape">, !transform.op<"linalg.transpose">)58      transform.yield59  }60}61 62// -----63 64// CHECK-LABEL: func.func @pack_as_pad(65// CHECK: %[[SRC:.+]]: tensor<129x47x16x16xf32>,66// CHECK: %[[OUT:.+]]: tensor<1x1x1x1x136x64x16x16xf32>)67func.func @pack_as_pad(%arg0: tensor<129x47x16x16xf32>, %arg1: tensor<1x1x1x1x136x64x16x16xf32>) -> tensor<1x1x1x1x136x64x16x16xf32> {68  %cst_0 = arith.constant 0.0 : f3269 70  // linalg.pack is lowered to tensor.pad + tensor.insert_slice71  //      CHECK: %[[PAD:.*]] = tensor.pad %[[SRC]] low[0, 0, 0, 0] high[7, 17, 0, 0]72  //      CHECK:   : tensor<129x47x16x16xf32> to tensor<136x64x16x16xf32>73  //      CHECK: %[[RES:.*]] = tensor.insert_slice %[[PAD]] into %[[OUT]]74  // offsets.75  // CHECK-SAME:   [0, 0, 0, 0, 0, 0, 0, 0]76  // sizes.77  // CHECK-SAME:   [1, 1, 1, 1, 136, 64, 16, 16]78  // strides multipliers.79  // CHECK-SAME:   [1, 1, 1, 1, 1, 1, 1, 1]80  // CHECK-SAME:   : tensor<136x64x16x16xf32> into tensor<1x1x1x1x136x64x16x16xf32>81  //      CHECK: return %[[RES]]82  %pack = linalg.pack %arg0 padding_value(%cst_0 : f32) inner_dims_pos = [0, 1, 2, 3] inner_tiles = [136, 64, 16, 16] into %arg183    : tensor<129x47x16x16xf32> -> tensor<1x1x1x1x136x64x16x16xf32>84  return %pack :  tensor<1x1x1x1x136x64x16x16xf32>85}86 87module attributes {transform.with_named_sequence} {88  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {89    %pack = transform.structured.match ops{["linalg.pack"]} in %module_op90      : (!transform.any_op) -> !transform.op<"linalg.pack">91    transform.structured.lower_pack %pack : (!transform.op<"linalg.pack">)92      -> (!transform.op<"tensor.pad">, !transform.op<"tensor.expand_shape">, !transform.op<"linalg.transpose">)93      transform.yield94  }95}96 97// -----98 99// This is same as pack_as_pad but since we explicitly added {lowerPadLikeWithInsertSlice = false}, it should not100// be lowered to insert_slice.101// CHECK-LABEL: func.func @pack_as_pad_disabled_insert_slice(102func.func @pack_as_pad_disabled_insert_slice(%arg0: tensor<129x47x16x16xf32>, %arg1: tensor<1x1x1x1x136x64x16x16xf32>) -> tensor<1x1x1x1x136x64x16x16xf32> {103  %cst_0 = arith.constant 0.0 : f32104  // linalg.pack is lowered to tensor.pad + tensor.expand_shape + linalg.transpose105  // CHECK-SAME: %[[ARG0:[^:]*]]: tensor<129x47x16x16xf32>106  //  CHECK-DAG: %[[PAD:.*]] = tensor.pad %[[ARG0]]107  //  CHECK-NOT: %[[RES:.*]] = tensor.insert_slice %[[PAD]]108  //      CHECK: %[[PAD_EXPANDED:.*]] = tensor.expand_shape %[[PAD]]109  //  CHECK-DAG: %[[RES:.*]] = linalg.transpose ins(%[[PAD_EXPANDED]]110  %pack = linalg.pack %arg0 padding_value(%cst_0 : f32) inner_dims_pos = [0, 1, 2, 3] inner_tiles = [136, 64, 16, 16] into %arg1111    : tensor<129x47x16x16xf32> -> tensor<1x1x1x1x136x64x16x16xf32>112  return %pack :  tensor<1x1x1x1x136x64x16x16xf32>113}114 115module attributes {transform.with_named_sequence} {116  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {117    %pack = transform.structured.match ops{["linalg.pack"]} in %module_op118      : (!transform.any_op) -> !transform.op<"linalg.pack">119    transform.structured.lower_pack %pack {lowerPadLikeWithInsertSlice = false}: (!transform.op<"linalg.pack">)120      -> (!transform.op<"tensor.pad">, !transform.op<"tensor.expand_shape">, !transform.op<"linalg.transpose">)121      transform.yield122  }123}124 125// -----126 127// Check that we don't lower the following pack as a pad.128// Although all the outer most dimensions in the resulting shape are 1s,129// some of the original dimensions are not part of the inner_dims_pos, hence130// some transpose needs to happen.131// CHECK-LABEL: func.func @pack_not_a_pad(132func.func @pack_not_a_pad(%arg0: tensor<129x47x16x16xf32>, %arg1: tensor<1x1x16x16x136x64xf32>) -> tensor<1x1x16x16x136x64xf32> {133  %cst_0 = arith.constant 0.0 : f32134 135  //      CHECK: tensor.pad {{.*}} low[0, 0, 0, 0]136  //      CHECK:   : tensor<129x47x16x16xf32> to tensor<136x64x16x16xf32>137  //      CHECK: tensor.expand_shape %{{.*}} [{{.*}}[0, 1], [2, 3], [4], [5]]138  // CHECK-SAME:   : tensor<136x64x16x16xf32> into tensor<1x136x1x64x16x16xf32>139  //      CHECK: linalg.transpose140  // CHECK-SAME:   ins(%{{.*}} : tensor<1x136x1x64x16x16xf32>)141  // CHECK-SAME:   outs(%{{.*}} : tensor<1x1x16x16x136x64xf32>)142  // CHECK-SAME:   permutation = [0, 2, 4, 5, 1, 3]143 144  %pack = linalg.pack %arg0 padding_value(%cst_0 : f32) inner_dims_pos = [0, 1] inner_tiles = [136, 64] into %arg1145    : tensor<129x47x16x16xf32> -> tensor<1x1x16x16x136x64xf32>146  return %pack :  tensor<1x1x16x16x136x64xf32>147}148 149module attributes {transform.with_named_sequence} {150  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {151    %pack = transform.structured.match ops{["linalg.pack"]} in %module_op152      : (!transform.any_op) -> !transform.op<"linalg.pack">153    transform.structured.lower_pack %pack : (!transform.op<"linalg.pack">)154      -> (!transform.op<"tensor.pad">, !transform.op<"tensor.expand_shape">, !transform.op<"linalg.transpose">)155      transform.yield156  }157}158 159// -----160// CHECK-LABEL: func.func @unpack(161func.func @unpack(%arg0: tensor<17x2x16x16x32x8xf32>, %arg1: tensor<129x47x16x16xf32>) -> tensor<129x47x16x16xf32> {162  %cst_0 = arith.constant 0.0 : f32163  // CHECK-SAME: %[[ARG0:.*]]: tensor<17x2x16x16x32x8xf32>, %[[ARG1:.*]]: tensor<129x47x16x16xf32>164  //      CHECK: %[[EMPTY:.*]] = tensor.empty() : tensor<17x8x2x32x16x16xf32>165  //      CHECK: %[[TRAN:.*]] = linalg.transpose166  // CHECK-SAME:    ins(%[[ARG0]] : tensor<17x2x16x16x32x8xf32>)167  // CHECK-SAME:   outs(%[[EMPTY]] : tensor<17x8x2x32x16x16xf32>)168  // CHECK-SAME:   permutation = [0, 5, 1, 4, 2, 3]169  //      CHECK: %[[CLP:.*]] = tensor.collapse_shape %[[TRAN]] {{\[}}[0, 1], [2, 3], [4], [5]]170  // CHECK-SAME:   : tensor<17x8x2x32x16x16xf32> into tensor<136x64x16x16xf32>171  //      CHECK: %[[SLICE:.*]] = tensor.extract_slice %[[CLP]][0, 0, 0, 0] [129, 47, 16, 16] [1, 1, 1, 1]172  // CHECK-SAME:   : tensor<136x64x16x16xf32> to tensor<129x47x16x16xf32>173  //      CHECK: linalg.copy ins(%[[SLICE]] : tensor<129x47x16x16xf32>)174  // CHECK-SAME:        outs(%[[ARG1]] : tensor<129x47x16x16xf32>)175  %unpack = linalg.unpack %arg0 inner_dims_pos = [1, 0] inner_tiles = [32, 8] into %arg1176    : tensor<17x2x16x16x32x8xf32> -> tensor<129x47x16x16xf32>177  return %unpack : tensor<129x47x16x16xf32>178}179 180module attributes {transform.with_named_sequence} {181  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {182    %unpack = transform.structured.match ops{["linalg.unpack"]} in %module_op183      : (!transform.any_op) -> !transform.op<"linalg.unpack">184    transform.structured.lower_unpack %unpack : (!transform.op<"linalg.unpack">)185      -> (!transform.op<"tensor.empty">,186          !transform.op<"linalg.transpose">,187          !transform.op<"tensor.collapse_shape">,188          !transform.op<"tensor.extract_slice">)189          transform.yield190  }191}192 193// -----194 195// CHECK-LABEL: func.func @unpack_with_identity_outer_dims_perm(196func.func @unpack_with_identity_outer_dims_perm(%arg0: tensor<17x2x16x16x32x8xf32>, %arg1: tensor<129x47x16x16xf32>) -> tensor<129x47x16x16xf32> {197  %cst_0 = arith.constant 0.0 : f32198  // CHECK-SAME: %[[ARG0:.*]]: tensor<17x2x16x16x32x8xf32>, %[[ARG1:.*]]: tensor<129x47x16x16xf32>199  //      CHECK: %[[EMPTY:.*]] = tensor.empty() : tensor<17x8x2x32x16x16xf32>200  //      CHECK: %[[TRAN:.*]] = linalg.transpose201  // CHECK-SAME:    ins(%[[ARG0]] : tensor<17x2x16x16x32x8xf32>)202  // CHECK-SAME:   outs(%[[EMPTY]] : tensor<17x8x2x32x16x16xf32>)203  // CHECK-SAME:   permutation = [0, 5, 1, 4, 2, 3]204  //      CHECK: %[[CLP:.*]] = tensor.collapse_shape %[[TRAN]] {{\[}}[0, 1], [2, 3], [4], [5]]205  // CHECK-SAME:   : tensor<17x8x2x32x16x16xf32> into tensor<136x64x16x16xf32>206  //      CHECK: %[[SLICE:.*]] = tensor.extract_slice %[[CLP]][0, 0, 0, 0] [129, 47, 16, 16] [1, 1, 1, 1]207  // CHECK-SAME:   : tensor<136x64x16x16xf32> to tensor<129x47x16x16xf32>208  //      CHECK: linalg.copy ins(%[[SLICE]] : tensor<129x47x16x16xf32>)209  // CHECK-SAME:        outs(%[[ARG1]] : tensor<129x47x16x16xf32>)210  %unpack = linalg.unpack %arg0 outer_dims_perm = [0, 1, 2, 3] inner_dims_pos = [1, 0] inner_tiles = [32, 8] into %arg1211    : tensor<17x2x16x16x32x8xf32> -> tensor<129x47x16x16xf32>212  return %unpack : tensor<129x47x16x16xf32>213}214 215module attributes {transform.with_named_sequence} {216  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {217    %unpack = transform.structured.match ops{["linalg.unpack"]} in %module_op218      : (!transform.any_op) -> !transform.op<"linalg.unpack">219    transform.structured.lower_unpack %unpack : (!transform.op<"linalg.unpack">)220      -> (!transform.op<"tensor.empty">,221          !transform.op<"linalg.transpose">,222          !transform.op<"tensor.collapse_shape">,223          !transform.op<"tensor.extract_slice">)224          transform.yield225  }226}227 228// -----229 230// When an unpack is a plain 'unpad', lower it to a simple extract_slice.231// CHECK-LABEL: func.func @unpack_as_pad(232func.func @unpack_as_pad(%arg0: tensor<1x1x1x1x136x64x16x16xf32>, %arg1: tensor<129x47x16x16xf32>) -> tensor<129x47x16x16xf32> {233  %cst_0 = arith.constant 0.0 : f32234 235  // CHECK-SAME: %[[ARG0:[^:]*]]: tensor<1x1x1x1x136x64x16x16xf32>236  //      CHECK: %[[RES:.*]] = tensor.extract_slice %[[ARG0]]237  // offsets.238  // CHECK-SAME:   [0, 0, 0, 0, 0, 0, 0, 0]239  // sizes.240  // CHECK-SAME:   [1, 1, 1, 1, 129, 47, 16, 16]241  // strides multiplers.242  // CHECK-SAME:   [1, 1, 1, 1, 1, 1, 1, 1]243  // CHECK-SAME:   : tensor<1x1x1x1x136x64x16x16xf32> to tensor<129x47x16x16xf32>244  %pack = linalg.unpack %arg0 inner_dims_pos = [0, 1, 2, 3] inner_tiles = [136, 64, 16, 16] into %arg1245    : tensor<1x1x1x1x136x64x16x16xf32> -> tensor<129x47x16x16xf32>246  return %pack : tensor<129x47x16x16xf32>247}248 249module attributes {transform.with_named_sequence} {250  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {251    %unpack = transform.structured.match ops{["linalg.unpack"]} in %module_op252      : (!transform.any_op) -> !transform.op<"linalg.unpack">253    transform.structured.lower_unpack %unpack : (!transform.op<"linalg.unpack">)254      -> (!transform.op<"tensor.empty">,255          !transform.op<"linalg.transpose">,256          !transform.op<"tensor.collapse_shape">,257          !transform.op<"tensor.extract_slice">)258          transform.yield259  }260}261 262// -----263 264// This is same as upack_as_pad but since we explicitly added {lowerUnpadLikeWithExtractSlice = false}, it should not265// be lowered to extract_slice.266// CHECK-LABEL: func.func @unpack_as_pad_disabled_extract_slice(267func.func @unpack_as_pad_disabled_extract_slice(%arg0: tensor<1x1x1x1x136x64x16x16xf32>, %arg1: tensor<129x47x16x16xf32>) -> tensor<129x47x16x16xf32> {268  %cst_0 = arith.constant 0.0 : f32269 270  // linalg.unpack is lowered to tensor.extract_slice + linalg.transpose + tensor.collapse_shape271  // CHECK-DAG: %[[ARG0:[^:]*]]: tensor<1x1x1x1x136x64x16x16xf32>272  // CHECK-NOT: %[[RES:.*]] = tensor.extract_slice %[[ARG0]]273  //     CHECK: %[[TRANSPOSED:.*]] = linalg.transpose ins(%[[ARG0]]274  //     CHECK: %[[COLLAPSED:.*]] = tensor.collapse_shape %[[TRANSPOSED]]275  // CHECK-DAG: %[[RES:.*]] = tensor.extract_slice %[[COLLAPSED]]276  %pack = linalg.unpack %arg0 inner_dims_pos = [0, 1, 2, 3] inner_tiles = [136, 64, 16, 16] into %arg1277    : tensor<1x1x1x1x136x64x16x16xf32> -> tensor<129x47x16x16xf32>278  return %pack : tensor<129x47x16x16xf32>279}280 281module attributes {transform.with_named_sequence} {282  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {283    %unpack = transform.structured.match ops{["linalg.unpack"]} in %module_op284      : (!transform.any_op) -> !transform.op<"linalg.unpack">285    transform.structured.lower_unpack %unpack {lowerUnpadLikeWithExtractSlice = false}: (!transform.op<"linalg.unpack">)286      -> (!transform.op<"tensor.empty">,287          !transform.op<"linalg.transpose">,288          !transform.op<"tensor.collapse_shape">,289          !transform.op<"tensor.extract_slice">)290          transform.yield291  }292}293 294// -----295 296// CHECK-LABEL: func.func @pack_with_outer_dims_perm(297func.func @pack_with_outer_dims_perm(%src: tensor<100x200x128x256xi32>,298                                     %dest: tensor<200x4x16x100x16x32xi32>)299    -> tensor<200x4x16x100x16x32xi32> {300  //      CHECK: tensor.pad {{.*}} low[0, 0, 0, 0]301  //      CHECK:   : tensor<100x200x128x256xi32> to tensor<100x200x128x256xi32>302  //      CHECK: tensor.expand_shape %{{.*}} [{{.*}}[0], [1], [2, 3], [4, 5]]303  // CHECK-SAME:   : tensor<100x200x128x256xi32> into tensor<100x200x4x32x16x16xi32>304  //      CHECK: linalg.transpose305  // CHECK-SAME:   ins(%{{.*}} : tensor<100x200x4x32x16x16xi32>)306  // CHECK-SAME:   outs(%{{.*}} : tensor<200x4x16x100x16x32xi32>)307  // CHECK-SAME:   permutation = [1, 2, 4, 0, 5, 3]308  %0 = linalg.pack %src309    outer_dims_perm = [1, 2, 3, 0]310    inner_dims_pos = [3, 2]311    inner_tiles = [16, 32]312    into %dest : tensor<100x200x128x256xi32> -> tensor<200x4x16x100x16x32xi32>313  return %0 : tensor<200x4x16x100x16x32xi32>314}315 316module attributes {transform.with_named_sequence} {317  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {318    %pack = transform.structured.match ops{["linalg.pack"]} in %module_op319      : (!transform.any_op) -> !transform.op<"linalg.pack">320    transform.structured.lower_pack %pack : (!transform.op<"linalg.pack">)321      -> (!transform.op<"tensor.pad">, !transform.op<"tensor.expand_shape">, !transform.op<"linalg.transpose">)322      transform.yield323  }324}325 326// -----327 328// CHECK-LABEL: func.func @pack_with_pad(329func.func @pack_with_pad(%src: tensor<4225x12xf32>, %dest: tensor<265x12x16x1xf32>)330    -> tensor<265x12x16x1xf32> {331  //      CHECK: tensor.pad {{.*}} low[0, 0]332  //      CHECK:   : tensor<4225x12xf32> to tensor<4240x12xf32>333  //      CHECK: tensor.expand_shape %{{.*}} {{\[}}[0, 1], [2, 3]]334  // CHECK-SAME:   : tensor<4240x12xf32> into tensor<265x16x12x1xf32>335  //      CHECK: linalg.transpose336  // CHECK-SAME:   ins(%{{[a-zA-Z0-9]*}} : tensor<265x16x12x1xf32>)337  // CHECK-SAME:   outs(%{{[a-zA-Z0-9]*}} : tensor<265x12x16x1xf32>)338  // CHECK-SAME:   permutation = [0, 2, 1, 3]339  %cst = arith.constant 0.000000e+00 : f32340  %0 = linalg.pack %src341    padding_value(%cst : f32)342    inner_dims_pos = [0, 1]343    inner_tiles = [16, 1] into %dest344    : tensor<4225x12xf32> -> tensor<265x12x16x1xf32>345  return %0 : tensor<265x12x16x1xf32>346}347 348module attributes {transform.with_named_sequence} {349  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {350    %pack = transform.structured.match ops{["linalg.pack"]} in %module_op351      : (!transform.any_op) -> !transform.op<"linalg.pack">352    transform.structured.lower_pack %pack : (!transform.op<"linalg.pack">)353      -> (!transform.op<"tensor.pad">, !transform.op<"tensor.expand_shape">, !transform.op<"linalg.transpose">)354      transform.yield355  }356}357 358// -----359 360// CHECK-LABEL: func.func @pack_with_pad_and_outer_dims_perm(361func.func @pack_with_pad_and_outer_dims_perm(%src: tensor<100x200x127x255xi32>,362                                             %dest: tensor<200x4x16x100x16x32xi32>)363    -> tensor<200x4x16x100x16x32xi32> {364  //      CHECK: tensor.pad {{.*}} low[0, 0, 0, 0]365  //      CHECK:   : tensor<100x200x127x255xi32> to tensor<100x200x128x256xi32>366  //      CHECK: tensor.expand_shape %{{.*}} [{{.*}}[0], [1], [2, 3], [4, 5]]367  // CHECK-SAME:   : tensor<100x200x128x256xi32> into tensor<100x200x4x32x16x16xi32>368  //      CHECK: linalg.transpose369  // CHECK-SAME:   ins(%{{.*}} : tensor<100x200x4x32x16x16xi32>)370  // CHECK-SAME:   outs(%{{.*}} : tensor<200x4x16x100x16x32xi32>)371  // CHECK-SAME:   permutation = [1, 2, 4, 0, 5, 3]372  %cst_0 = arith.constant 0 : i32373  %0 = linalg.pack %src374    padding_value(%cst_0 : i32)375    outer_dims_perm = [1, 2, 3, 0]376    inner_dims_pos = [3, 2]377    inner_tiles = [16, 32]378    into %dest : tensor<100x200x127x255xi32> -> tensor<200x4x16x100x16x32xi32>379  return %0 : tensor<200x4x16x100x16x32xi32>380}381 382module attributes {transform.with_named_sequence} {383  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {384    %pack = transform.structured.match ops{["linalg.pack"]} in %module_op385      : (!transform.any_op) -> !transform.op<"linalg.pack">386    transform.structured.lower_pack %pack : (!transform.op<"linalg.pack">)387      -> (!transform.op<"tensor.pad">, !transform.op<"tensor.expand_shape">, !transform.op<"linalg.transpose">)388      transform.yield389  }390}391 392// -----393 394// CHECK-DAG:   #[[MAP0:.+]] = affine_map<()[s0, s1] -> (s0 * 16 - s1)>395// CHECK-DAG:   #[[MAP1:.+]] = affine_map<()[s0, s1] -> (s0 * 32 - s1)>396// CHECK:       func.func @dynamic_pack_pad_transpose_inner_and_outer_dims(397// CHECK-SAME:    %[[SRC:[a-zA-Z0-9]+]]398func.func @dynamic_pack_pad_transpose_inner_and_outer_dims(%source: tensor<?x?xf32>) -> tensor<?x?x16x32xf32> {399  // CHECK-DAG:   %[[C0:.+]] = arith.constant 0 : index400  // CHECK-DAG:   %[[C1:.+]] = arith.constant 1 : index401  // CHECK-DAG:   %[[C16:.+]] = arith.constant 16 : index402  // CHECK-DAG:   %[[C32:.+]] = arith.constant 32 : index403  // CHECK-DAG:   %[[D0:.+]] = tensor.dim %[[SRC]], %[[C0]]404  // CHECK-DAG:   %[[D1:.+]] = tensor.dim %[[SRC]], %[[C1]]405  // CHECK-DAG:   %[[OUT_D0:.+]] = arith.ceildivui %[[D1]], %[[C16]] : index406  // CHECK-DAG:   %[[OUT_D1:.+]] = arith.ceildivui %[[D0]], %[[C32]] : index407  // CHECK-DAG:   %[[EMPTY:.+]] = tensor.empty(%[[OUT_D0]], %[[OUT_D1]]) : tensor<?x?x16x32xf32>408  // CHECK-DAG:   %[[DEST_D0:.+]] = tensor.dim %[[EMPTY]], %[[C0]]409  // CHECK-DAG:   %[[DEST_D1:.+]] = tensor.dim %[[EMPTY]], %[[C1]]410  // CHECK-DAG:   %[[H1:.+]] = affine.apply #[[MAP0]]()[%[[DEST_D0]], %[[D1]]]411  // CHECK-DAG:   %[[H0:.+]] = affine.apply #[[MAP1]]()[%[[DEST_D1]], %[[D0]]]412  // CHECK:       %[[PAD:.+]] = tensor.pad %[[SRC]] low[0, 0] high[%[[H0]], %[[H1]]]413  // CHECK:         : tensor<?x?xf32> to tensor<?x?xf32>414  // CHECK:       %[[EXPAND:.+]] = tensor.expand_shape %[[PAD]] {{\[}}[0, 1], [2, 3]]415  // CHECK-SAME:   : tensor<?x?xf32> into tensor<?x32x?x16xf32>416  // CHECK:       %[[TRANSP:.+]] = linalg.transpose417  // CHECK-SAME:    ins(%[[EXPAND]] : tensor<?x32x?x16xf32>)418  // CHECK-SAME:    outs(%[[EMPTY]] : tensor<?x?x16x32xf32>)419  // CHECK-SAME:    permutation = [2, 0, 3, 1]420  // CHECK:       return %[[TRANSP]]421  %c0 = arith.constant 0 : index422  %c1 = arith.constant 1 : index423  %d0 = tensor.dim %source, %c0 : tensor<?x?xf32>424  %d1 = tensor.dim %source, %c1 : tensor<?x?xf32>425  %padding_value = arith.constant 0.0 : f32426 427  %c16 = arith.constant 16 : index428  %c32 = arith.constant 32 : index429  %tiled_d0 = arith.ceildivui %d0, %c32 : index430  %tiled_d1 = arith.ceildivui %d1, %c16 : index431  %init_pack = tensor.empty(%tiled_d1, %tiled_d0) : tensor<?x?x16x32xf32>432  %pack = linalg.pack %source padding_value(%padding_value : f32)433      outer_dims_perm = [1, 0] inner_dims_pos = [1, 0] inner_tiles = [16, 32] into %init_pack434      : tensor<?x?xf32> -> tensor<?x?x16x32xf32>435  return %pack : tensor<?x?x16x32xf32>436}437 438module attributes {transform.with_named_sequence} {439  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {440    %pack = transform.structured.match ops{["linalg.pack"]} in %module_op441      : (!transform.any_op) -> !transform.op<"linalg.pack">442    transform.structured.lower_pack %pack : (!transform.op<"linalg.pack">)443      -> (!transform.op<"tensor.pad">, !transform.op<"tensor.expand_shape">, !transform.op<"linalg.transpose">)444      transform.yield445  }446}447 448// -----449 450// CHECK-LABEL: func.func @pack_as_pad_with_outer_dims_perm(451// CHECK: %[[SRC:.+]]: tensor<129x47x16x16xf32>,452// CHECK: %[[OUT:.+]]: tensor<1x1x1x1x136x64x16x16xf32>)453func.func @pack_as_pad_with_outer_dims_perm(%arg0: tensor<129x47x16x16xf32>, %arg1: tensor<1x1x1x1x136x64x16x16xf32>) -> tensor<1x1x1x1x136x64x16x16xf32> {454  %cst_0 = arith.constant 0.0 : f32455 456  // linalg.pack is lowered to tensor.pad + tensor.insert_slice457  //      CHECK: %[[PAD:.*]] = tensor.pad %[[SRC]] low[0, 0, 0, 0] high[7, 17, 0, 0]458  //      CHECK:   : tensor<129x47x16x16xf32> to tensor<136x64x16x16xf32>459  //      CHECK: %[[RES:.*]] = tensor.insert_slice %[[PAD]] into %[[OUT]]460  // offsets.461  // CHECK-SAME:   [0, 0, 0, 0, 0, 0, 0, 0]462  // sizes.463  // CHECK-SAME:   [1, 1, 1, 1, 136, 64, 16, 16]464  // strides multipliers.465  // CHECK-SAME:   [1, 1, 1, 1, 1, 1, 1, 1]466  // CHECK-SAME:   : tensor<136x64x16x16xf32> into tensor<1x1x1x1x136x64x16x16xf32>467  //      CHECK: return %[[RES]]468  %pack = linalg.pack %arg0469    padding_value(%cst_0 : f32)470    outer_dims_perm = [1, 2, 3, 0]471    inner_dims_pos = [0, 1, 2, 3]472    inner_tiles = [136, 64, 16, 16]473    into %arg1 : tensor<129x47x16x16xf32> -> tensor<1x1x1x1x136x64x16x16xf32>474  return %pack :  tensor<1x1x1x1x136x64x16x16xf32>475}476 477module attributes {transform.with_named_sequence} {478  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {479    %pack = transform.structured.match ops{["linalg.pack"]} in %module_op480      : (!transform.any_op) -> !transform.op<"linalg.pack">481    transform.structured.lower_pack %pack : (!transform.op<"linalg.pack">)482      -> (!transform.op<"tensor.pad">, !transform.op<"tensor.expand_shape">, !transform.op<"linalg.transpose">)483      transform.yield484  }485}486 487// -----488 489// CHECK-LABEL: func.func @pack_as_pad_with_unit_dims(490// CHECK: %[[SRC:.+]]: tensor<3x1x1x1xf32>,491// CHECK: %[[OUT:.+]]: tensor<1x1x1x1x8x1xf32>)492func.func @pack_as_pad_with_unit_dims(%arg0: tensor<3x1x1x1xf32>, %arg1: tensor<1x1x1x1x8x1xf32>) -> (tensor<1x1x1x1x8x1xf32>) {493  %zero = arith.constant 0.0 : f32494 495  // CHECK:      %[[PAD:.+]] = tensor.pad %[[SRC]] low[0, 0, 0, 0] high[5, 0, 0, 0] {496  // CHECK:        : tensor<3x1x1x1xf32> to tensor<8x1x1x1xf32>497  // CHECK:      %[[EXPAND:.+]] = tensor.expand_shape %[[PAD]] [{{.*}}[0, 1], [2, 3], [4], [5]]498  // CHECK-SAME:   tensor<8x1x1x1xf32> into tensor<1x8x1x1x1x1xf32>499  // CHECK:      %[[TRANSPOSED:.+]] = linalg.transpose500  // CHECK-SAME:   ins(%[[EXPAND]] : tensor<1x8x1x1x1x1xf32>)501  // CHECK-SAME:   outs(%[[OUT]] : tensor<1x1x1x1x8x1xf32>)502  // CHECK-SAME:   permutation = [0, 2, 4, 5, 1, 3]503  // CHECK:      return %[[TRANSPOSED]] : tensor<1x1x1x1x8x1xf32>504  %pack = linalg.pack %arg0505      padding_value(%zero : f32)506      inner_dims_pos = [0, 1]507      inner_tiles = [8, 1] into %arg1 : tensor<3x1x1x1xf32> -> tensor<1x1x1x1x8x1xf32>508 509  return %pack : tensor<1x1x1x1x8x1xf32>510}511 512 513module attributes {transform.with_named_sequence} {514  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {515    %pack = transform.structured.match ops{["linalg.pack"]} in %module_op516      : (!transform.any_op) -> !transform.op<"linalg.pack">517    transform.structured.lower_pack %pack : (!transform.op<"linalg.pack">)518      -> (!transform.op<"tensor.pad">, !transform.op<"tensor.expand_shape">, !transform.op<"linalg.transpose">)519      transform.yield520  }521}522 523// -----524 525// Check that we can lower unpack with dynamic dimensions in the destination.526// CHECK-LABEL: func.func @unpack_with_dynamic_dest(527// CHECK-SAME: %[[ARG0:.*]]: tensor<32x2x49x16x16xf32>, %[[ARG1:.*]]: tensor<32x?x?xf32>)528//      CHECK: %[[EMPTY:.*]] = tensor.empty() : tensor<32x2x16x49x16xf32>529//      CHECK: %[[TRAN:.*]] = linalg.transpose530// CHECK-SAME:    ins(%[[ARG0]] : tensor<32x2x49x16x16xf32>)531// CHECK-SAME:   outs(%[[EMPTY]] : tensor<32x2x16x49x16xf32>)532// CHECK-SAME:   permutation = [0, 1, 3, 2, 4]533//      CHECK: %[[CLP:.*]] = tensor.collapse_shape %[[TRAN]] {{\[}}[0], [1, 2], [3, 4]]534// CHECK-SAME:   : tensor<32x2x16x49x16xf32> into tensor<32x32x784xf32>535//      CHECK:  %[[C1:.*]] = arith.constant 1 : index536//      CHECK: %[[DIM1:.*]] = tensor.dim %[[ARG1]], %[[C1]] : tensor<32x?x?xf32>537//      CHECK: %[[C2:.*]] = arith.constant 2 : index538//      CHECK: %[[DIM2:.*]] = tensor.dim %[[ARG1]], %[[C2]] : tensor<32x?x?xf32>539//      CHECK: %[[SLICE:.*]] = tensor.extract_slice %[[CLP]][0, 0, 0] [32, %[[DIM1]], %[[DIM2]]] [1, 1, 1]540// CHECK-SAME:   : tensor<32x32x784xf32> to tensor<32x?x?xf32>541//      CHECK: linalg.copy ins(%[[SLICE]] : tensor<32x?x?xf32>)542// CHECK-SAME:        outs(%[[ARG1]] : tensor<32x?x?xf32>)543func.func @unpack_with_dynamic_dest(%arg0: tensor<32x2x49x16x16xf32>, %arg1: tensor<32x?x?xf32>) -> tensor<32x?x?xf32> {544  %pack = linalg.unpack %arg0 inner_dims_pos = [1, 2] inner_tiles = [16, 16] into %arg1545    : tensor<32x2x49x16x16xf32> -> tensor<32x?x?xf32>546  return %pack : tensor<32x?x?xf32>547}548 549module attributes {transform.with_named_sequence} {550  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {551    %unpack = transform.structured.match ops{["linalg.unpack"]} in %module_op552      : (!transform.any_op) -> !transform.op<"linalg.unpack">553    transform.structured.lower_unpack %unpack : (!transform.op<"linalg.unpack">)554      -> (!transform.op<"tensor.empty">,555          !transform.op<"linalg.transpose">,556          !transform.op<"tensor.collapse_shape">,557          !transform.op<"tensor.extract_slice">)558          transform.yield559  }560}561 562// -----563 564// Check that we can lower unpack with dynamic dimensions in the input and destination.565// CHECK-LABEL: func.func @unpack_with_dynamic_input_dest(566// CHECK-SAME: %[[ARG0:.*]]: tensor<?x?x8x16xf32>, %[[ARG1:.*]]: tensor<?x?xf32>)567//      CHECK-DAG:  %[[C0:.*]] = arith.constant 0 : index568//      CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index569//      CHECK-DAG: %[[DIM00:.*]] = tensor.dim %[[ARG0]], %[[C0]]570//      CHECK-DAG: %[[DIM01:.*]] = tensor.dim %[[ARG0]], %[[C1]]571//      CHECK: %[[EMPTY:.*]] = tensor.empty(%[[DIM00]], %[[DIM01]]) : tensor<?x8x?x16xf32>572//      CHECK: %[[TRAN:.*]] = linalg.transpose573// CHECK-SAME:    ins(%[[ARG0]] : tensor<?x?x8x16xf32>)574// CHECK-SAME:   outs(%[[EMPTY]] : tensor<?x8x?x16xf32>)575// CHECK-SAME:   permutation = [0, 2, 1, 3]576//      CHECK: %[[CLP:.*]] = tensor.collapse_shape %[[TRAN]] {{\[}}[0, 1], [2, 3]]577// CHECK-SAME:   : tensor<?x8x?x16xf32> into tensor<?x?xf32>578//      CHECK: %[[DIM10:.*]] = tensor.dim %[[ARG1]], %[[C0]] : tensor<?x?xf32>579//      CHECK: %[[DIM11:.*]] = tensor.dim %[[ARG1]], %[[C1]] : tensor<?x?xf32>580//      CHECK: %[[SLICE:.*]] = tensor.extract_slice %[[CLP]][0, 0] [%[[DIM10]], %[[DIM11]]] [1, 1]581// CHECK-SAME:   : tensor<?x?xf32> to tensor<?x?xf32>582//      CHECK: linalg.copy ins(%[[SLICE]] : tensor<?x?xf32>)583// CHECK-SAME:        outs(%[[ARG1]] : tensor<?x?xf32>)584func.func @unpack_with_dynamic_input_dest(%arg0: tensor<?x?x8x16xf32>, %arg1: tensor<?x?xf32>) -> tensor<?x?xf32> {585    %unpack = linalg.unpack %arg0 inner_dims_pos = [0, 1] inner_tiles = [8, 16] into %arg1 : tensor<?x?x8x16xf32> -> tensor<?x?xf32>586    return %unpack : tensor<?x?xf32>587}588 589module attributes {transform.with_named_sequence} {590  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {591    %unpack = transform.structured.match ops{["linalg.unpack"]} in %module_op592      : (!transform.any_op) -> !transform.op<"linalg.unpack">593    transform.structured.lower_unpack %unpack : (!transform.op<"linalg.unpack">)594      -> (!transform.op<"tensor.empty">,595          !transform.op<"linalg.transpose">,596          !transform.op<"tensor.collapse_shape">,597          !transform.op<"tensor.extract_slice">)598          transform.yield599  }600}601 602// -----603 604// Check that we can lower unpack with dynamic dimensions in the input, destination, inner_tiles.605// CHECK-LABEL: func.func @unpack_fully_dynamic(606// CHECK-SAME: %[[ARG0:.*]]: tensor<?x?x?x?xf32>, %[[ARG1:.*]]: tensor<?x?xf32>, %[[ARG2:.*]]: index, %[[ARG3:.*]]: index)607//      CHECK-DAG:  %[[C0:.*]] = arith.constant 0 : index608//      CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index609//      CHECK-DAG:  %[[C2:.*]] = arith.constant 2 : index610//      CHECK-DAG: %[[C3:.*]] = arith.constant 3 : index611//      CHECK-DAG: %[[DIM00:.*]] = tensor.dim %[[ARG0]], %[[C0]]612//      CHECK-DAG: %[[DIM01:.*]] = tensor.dim %[[ARG0]], %[[C1]]613//      CHECK-DAG: %[[DIM02:.*]] = tensor.dim %[[ARG0]], %[[C2]]614//      CHECK-DAG: %[[DIM03:.*]] = tensor.dim %[[ARG0]], %[[C3]]615//      CHECK: %[[EMPTY:.*]] = tensor.empty(%[[DIM00]], %[[DIM02]], %[[DIM01]], %[[DIM03]]) : tensor<?x?x?x?xf32>616//      CHECK: %[[TRAN:.*]] = linalg.transpose617// CHECK-SAME:    ins(%[[ARG0]] : tensor<?x?x?x?xf32>)618// CHECK-SAME:   outs(%[[EMPTY]] : tensor<?x?x?x?xf32>)619// CHECK-SAME:   permutation = [0, 2, 1, 3]620//      CHECK: %[[CLP:.*]] = tensor.collapse_shape %[[TRAN]] {{\[}}[0, 1], [2, 3]]621// CHECK-SAME:   : tensor<?x?x?x?xf32> into tensor<?x?xf32>622//      CHECK: %[[DIM10:.*]] = tensor.dim %[[ARG1]], %[[C0]] : tensor<?x?xf32>623//      CHECK: %[[DIM11:.*]] = tensor.dim %[[ARG1]], %[[C1]] : tensor<?x?xf32>624//      CHECK: %[[SLICE:.*]] = tensor.extract_slice %[[CLP]][0, 0] [%[[DIM10]], %[[DIM11]]] [1, 1]625// CHECK-SAME:   : tensor<?x?xf32> to tensor<?x?xf32>626//      CHECK: linalg.copy ins(%[[SLICE]] : tensor<?x?xf32>)627// CHECK-SAME:        outs(%[[ARG1]] : tensor<?x?xf32>)628func.func @unpack_fully_dynamic(%source: tensor<?x?x?x?xf32>, %dest: tensor<?x?xf32>, %tile_n : index, %tile_m : index) -> tensor<?x?xf32> {629  %0 = linalg.unpack %source inner_dims_pos = [0, 1] inner_tiles = [%tile_n, %tile_m] into %dest : tensor<?x?x?x?xf32> -> tensor<?x?xf32>630  return %0 : tensor<?x?xf32>631}632module attributes {transform.with_named_sequence} {633  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {634    %unpack = transform.structured.match ops{["linalg.unpack"]} in %module_op635      : (!transform.any_op) -> !transform.op<"linalg.unpack">636    transform.structured.lower_unpack %unpack : (!transform.op<"linalg.unpack">)637          -> (!transform.op<"tensor.empty">,638          !transform.op<"linalg.transpose">,639          !transform.op<"tensor.collapse_shape">,640          !transform.op<"tensor.extract_slice">)641      transform.yield642  }643}644 645// -----646 647// Check that we can lower unpack "as unpad" with dynamic dims.648// CHECK-LABEL: func.func @unpack_as_pad_dynamic(649// CHECK-SAME: %[[ARG0:.*]]: tensor<1x1x1x1x136x64x16x16xf32>, %[[ARG1:.*]]: tensor<?x?x?x?xf32>650//      CHECK-DAG:  %[[C0:.*]] = arith.constant 0 : index651//      CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index652//      CHECK-DAG:  %[[C2:.*]] = arith.constant 2 : index653//      CHECK-DAG: %[[C3:.*]] = arith.constant 3 : index654//      CHECK-DAG: %[[DIM0:.*]] = tensor.dim %[[ARG1]], %[[C0]]655//      CHECK-DAG: %[[DIM1:.*]] = tensor.dim %[[ARG1]], %[[C1]]656//      CHECK-DAG: %[[DIM2:.*]] = tensor.dim %[[ARG1]], %[[C2]]657//      CHECK-DAG: %[[DIM3:.*]] = tensor.dim %[[ARG1]], %[[C3]]658//      CHECK: %[[RES:.*]] = tensor.extract_slice %[[ARG0]]659// offsets.660// CHECK-SAME:   [0, 0, 0, 0, 0, 0, 0, 0]661// sizes.662// CHECK-SAME:   [1, 1, 1, 1, %[[DIM0]], %[[DIM1]], %[[DIM2]], %[[DIM3]]]663// strides multiplers.664// CHECK-SAME:   [1, 1, 1, 1, 1, 1, 1, 1]665// CHECK-SAME:   :  tensor<1x1x1x1x136x64x16x16xf32> to tensor<?x?x?x?xf32>666func.func @unpack_as_pad_dynamic(%arg0: tensor<1x1x1x1x136x64x16x16xf32>, %arg1: tensor<?x?x?x?xf32>) -> tensor<?x?x?x?xf32> {667  %pack = linalg.unpack %arg0 inner_dims_pos = [0, 1, 2, 3] inner_tiles = [136, 64, 16, 16] into %arg1668    : tensor<1x1x1x1x136x64x16x16xf32> -> tensor<?x?x?x?xf32>669  return %pack : tensor<?x?x?x?xf32>670}671 672module attributes {transform.with_named_sequence} {673  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {674    %unpack = transform.structured.match ops{["linalg.unpack"]} in %module_op675      : (!transform.any_op) -> !transform.op<"linalg.unpack">676    transform.structured.lower_unpack %unpack : (!transform.op<"linalg.unpack">)677      -> (!transform.op<"tensor.empty">,678          !transform.op<"linalg.transpose">,679          !transform.op<"tensor.collapse_shape">,680          !transform.op<"tensor.extract_slice">)681          transform.yield682  }683}684 685// -----686 687// CHECK-LABEL: @unpack_with_outer_dims_perm688//  CHECK-SAME: %[[ARG0:.*]]: tensor<32x64xf32>, %[[ARG1:.*]]: tensor<2x4x32x8xf32>689//       CHECK: %[[EMPTY:.*]] = tensor.empty() : tensor<4x8x2x32xf32>690//       CHECK: %[[TRAN:.*]] = linalg.transpose691//  CHECK-SAME:   ins(%[[ARG1]] : tensor<2x4x32x8xf32>)692//  CHECK-SAME:   outs(%[[EMPTY]] : tensor<4x8x2x32xf32>)693//  CHECK-SAME:   permutation = [1, 3, 0, 2]694//       CHECK: %[[CLP:.*]] = tensor.collapse_shape %[[TRAN]] {{\[}}[0, 1], [2, 3]]695//  CHECK-SAME:   : tensor<4x8x2x32xf32> into tensor<32x64xf32>696//       CHECK: %[[SLICE:.*]] = tensor.extract_slice %[[CLP]][0, 0] [32, 64] [1, 1]697//  CHECK-SAME:   : tensor<32x64xf32> to tensor<32x64xf32>698//       CHECK: linalg.copy ins(%[[SLICE]]699//  CHECK-SAME:   : tensor<32x64xf32>) outs(%[[ARG0]] : tensor<32x64xf32>) -> tensor<32x64xf32>700func.func @unpack_with_outer_dims_perm(%arg0: tensor<32x64xf32>, %arg1: tensor<2x4x32x8xf32>) -> tensor<32x64xf32> {701  %unpack = linalg.unpack %arg1 outer_dims_perm = [1, 0]702    inner_dims_pos = [1, 0] inner_tiles = [32, 8] into %arg0 : tensor<2x4x32x8xf32> -> tensor<32x64xf32>703  return %unpack : tensor<32x64xf32>704}705 706module attributes {transform.with_named_sequence} {707  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {708    %unpack = transform.structured.match ops{["linalg.unpack"]} in %module_op709      : (!transform.any_op) -> !transform.op<"linalg.unpack">710    transform.structured.lower_unpack %unpack : (!transform.op<"linalg.unpack">)711      -> (!transform.op<"tensor.empty">,712          !transform.op<"linalg.transpose">,713          !transform.op<"tensor.collapse_shape">,714          !transform.op<"tensor.extract_slice">)715          transform.yield716  }717}718