brintos

brintos / llvm-project-archived public Read only

0
0
Text · 57.2 KiB · 66cae5c Raw
1144 lines · plain
1// RUN: mlir-opt %s --pass-pipeline="builtin.module(transform-interpreter{debug-payload-root-tag=start_here})" --split-input-file --verify-diagnostics2 3module attributes { transform.with_named_sequence } {4  transform.named_sequence @print_structured(%arg0: !transform.any_op {transform.readonly}) {5    transform.debug.emit_remark_at %arg0, "structured" : !transform.any_op6    transform.yield7  }8 9  transform.named_sequence @match_structured_empty(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op {10    %0 = transform.match.structured %arg0 : (!transform.any_op) -> !transform.any_op {11    ^bb0(%arg1: !transform.any_op):12          transform.match.structured.yield %arg1 : !transform.any_op13    }14    transform.yield %0 : !transform.any_op15  }16 17  // Entry point. Match any structured operation and emit at remark.18  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {19    transform.foreach_match in %arg020        @match_structured_empty -> @print_structured21        : (!transform.any_op) -> !transform.any_op22    transform.yield23  }24 25  func.func @payload() attributes { transform.target_tag = "start_here" } {26    %preA = tensor.empty() : tensor<2x3xf32>27    %cA = arith.constant 1.0 : f3228    // expected-remark @below {{structured}}29    %A = linalg.fill ins(%cA : f32) outs(%preA : tensor<2x3xf32>) -> tensor<2x3xf32>30 31    %B = arith.constant dense<1.0> : tensor<3x4xf32>32    %C = arith.constant dense<1000.0> : tensor<2x4xf32>33    // expected-remark @below {{structured}}34    %D = linalg.matmul ins(%A, %B: tensor<2x3xf32>, tensor<3x4xf32>)35                       outs(%C: tensor<2x4xf32>) -> tensor<2x4xf32>36 37    %E = arith.constant dense<2.0> : tensor<2x4xf32>38    // expected-remark @below {{structured}}39    linalg.generic {40      indexing_maps = [affine_map<(d0, d1) -> (d0, d1)>, affine_map<(d0, d1) -> (d0, d1)>],41      iterator_types = ["parallel", "parallel"]42    } ins(%D : tensor<2x4xf32>) outs(%E : tensor<2x4xf32>) {43    ^bb0(%arg0: f32, %arg1: f32):44      linalg.yield %arg0 : f3245    } -> tensor<2x4xf32>46 47    return48  }49}50 51// -----52 53module attributes { transform.with_named_sequence } {54  transform.named_sequence @do_nothing(%arg0: !transform.any_op {transform.readonly}) {55    transform.yield56  }57 58  transform.named_sequence @print_in_matcher(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op {59    transform.print %arg0 : !transform.any_op60    transform.yield %arg0 : !transform.any_op61  }62 63  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {64    transform.foreach_match in %arg065        @print_in_matcher -> @do_nothing66        : (!transform.any_op) -> !transform.any_op67    transform.yield68  }69 70  func.func @payload() attributes { transform.target_tag = "start_here" } {71    // CHECK: [[ IR Printer ]]72    // CHECK: test.print_me73    %0 = "test.print_me"() : () -> (i1)74    return75  }76}77 78// -----79 80 81module attributes { transform.with_named_sequence } {82  transform.named_sequence @do_nothing(%arg0: !transform.any_op {transform.readonly}) {83    transform.yield84  }85 86  // Entry point. Match any structured operation and emit a remark. Also emit87  // a different remark at all considered operations. When it fails, the88  // failure is suppressed and the resulting handle is assocaited with an empty89  // list, hence nothing is printed. Both remark printing operations happen90  // after the check in the sequence, so they only apply if the check operation91  // produced success (due to failure suppression or not).92  transform.named_sequence @match_structured_suppress(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op {93    %0 = transform.match.structured failures(suppress) %arg0 : (!transform.any_op) -> !transform.any_op {94    ^bb0(%arg1: !transform.any_op):95      transform.match.structured.yield %arg1 : !transform.any_op96    }97    transform.debug.emit_remark_at %0, "structured" : !transform.any_op98    transform.debug.emit_remark_at %arg0, "other" : !transform.any_op99    transform.yield %0 : !transform.any_op100  }101 102  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {103    transform.foreach_match restrict_root in %arg0104        @match_structured_suppress -> @do_nothing105        : (!transform.any_op) -> !transform.any_op106    transform.yield107  }108 109  // expected-remark @below {{other}}110  func.func @payload() attributes { transform.target_tag = "start_here" } {111    // expected-remark @below {{other}}112    %D = arith.constant dense<1.0> : tensor<2x4xf32>113    // expected-remark @below {{other}}114    %E = arith.constant dense<2.0> : tensor<2x4xf32>115    // expected-remark @below {{structured}}116    // expected-remark @below {{other}}117    linalg.generic {118      indexing_maps = [affine_map<(d0, d1) -> (d0, d1)>, affine_map<(d0, d1) -> (d0, d1)>],119      iterator_types = ["parallel", "parallel"]120    } ins(%D : tensor<2x4xf32>) outs(%E : tensor<2x4xf32>) {121    ^bb0(%arg0: f32, %arg1: f32):122      // expected-remark @below {{other}}123      linalg.yield %arg0 : f32124    } -> tensor<2x4xf32>125 126    // expected-remark @below {{other}}127    return128  }129}130 131// -----132 133module attributes { transform.with_named_sequence } {134  transform.named_sequence @print_passthrough(%arg0: !transform.any_op {transform.readonly}) {135    transform.debug.emit_remark_at %arg0, "passthrough" : !transform.any_op136    transform.yield137  }138 139  transform.named_sequence @match_structured_body_passthrough(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op {140    %0 = transform.match.structured failures(propagate) %arg0 : (!transform.any_op) -> !transform.any_op {141    ^bb0(%arg1: !transform.any_op):142      transform.match.structured.body %arg1 { passthrough } : !transform.any_op143      transform.match.structured.yield %arg1 : !transform.any_op144    }145    transform.yield %0 : !transform.any_op146  }147 148  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {149    transform.foreach_match in %arg0150        @match_structured_body_passthrough -> @print_passthrough151        : (!transform.any_op) -> !transform.any_op152    transform.yield153  }154 155  func.func @payload(%in: tensor<2xf32>, %out: tensor<2xf32>) attributes { transform.target_tag = "start_here" } {156    // expected-remark @below {{passthrough}}157    linalg.generic {158      indexing_maps = [affine_map<(d0) -> (d0)>, affine_map<(d0) -> (d0)>],159      iterator_types = ["parallel"]160    } ins(%in : tensor<2xf32>) outs(%out : tensor<2xf32>) {161    ^bb0(%arg0: f32, %arg1: f32):162      linalg.yield %arg0 : f32163    } -> tensor<2xf32>164 165    linalg.generic {166      indexing_maps = [affine_map<(d0) -> (d0)>, affine_map<(d0) -> (d0)>],167      iterator_types = ["parallel"]168    } ins(%in : tensor<2xf32>) outs(%out : tensor<2xf32>) {169    ^bb0(%arg0: f32, %arg1: f32):170      %0 = arith.mulf %arg0, %arg1 : f32171      linalg.yield %0 : f32172    } -> tensor<2xf32>173 174    // expected-remark @below {{passthrough}}175    linalg.copy ins(%in : tensor<2xf32>) outs(%out : tensor<2xf32>) -> tensor<2xf32>176 177    return178  }179}180 181// -----182 183module attributes { transform.with_named_sequence } {184  transform.named_sequence @print_elementwise(%arg0: !transform.any_op {transform.readonly}) {185    transform.debug.emit_remark_at %arg0, "elementwise" : !transform.any_op186    transform.yield187  }188 189  transform.named_sequence @match_structured_body_elementwise(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op {190    %0 = transform.match.structured failures(propagate) %arg0 : (!transform.any_op) -> !transform.any_op {191    ^bb0(%arg1: !transform.any_op):192      transform.match.structured.body %arg1 { elementwise } : !transform.any_op193      transform.match.structured.yield %arg1 : !transform.any_op194    }195    transform.yield %0 : !transform.any_op196  }197 198  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {199    transform.foreach_match in %arg0200        @match_structured_body_elementwise -> @print_elementwise201        : (!transform.any_op) -> !transform.any_op202    transform.yield203  }204 205  func.func @payload(%in1: tensor<2xf32>, %in2: tensor<2xf32>, %in3: tensor<2x3xf32>, %out: tensor<2xf32>, %out2: tensor<2x3xf32>) -> (tensor<2xf32>, tensor<2x3xf32>, tensor<2x3xf32>) attributes { transform.target_tag = "start_here" } {206    %cst0 = arith.constant 0.0 : f32207    %c0 = arith.constant 0 : index208    %c1 = arith.constant 1 : index209    // expected-remark @below {{elementwise}}210    %fill = linalg.fill ins(%cst0: f32) outs(%out: tensor<2xf32>) -> tensor<2xf32>211    // expected-remark @below {{elementwise}}212    %add = linalg.map {arith.addf} ins(%in1, %in2: tensor<2xf32>, tensor<2xf32>) outs(%fill: tensor<2xf32>)213    %non_elementwise = linalg.generic214      {indexing_maps = [affine_map<(d0, d1) -> (d0)>, affine_map<(d0, d1) -> (d0, d1)>, affine_map<(d0, d1) -> (d0, d1)>],215       iterator_types = ["parallel", "parallel"]}216      ins(%in1, %in3: tensor<2xf32>, tensor<2x3xf32>) outs(%out2: tensor<2x3xf32>) {217        ^bb0(%arg0: f32, %arg1: f32, %arg3: f32):218          %0 = arith.addf %arg0, %arg1 : f32219          %1 = tensor.dim %add, %c0 : tensor<2xf32>220          %2 = arith.subi %1, %c1 : index221          %3 = tensor.extract %add[%2] : tensor<2xf32>222          %4 = arith.mulf %0, %3 : f32223          linalg.yield %4 : f32224      } -> tensor<2x3xf32>225    // expected-remark @below {{elementwise}}226    %add_bcast = linalg.generic227      {indexing_maps = [affine_map<(d0, d1) -> (d0)>, affine_map<(d0, d1) -> (d0, d1)>, affine_map<(d0, d1) -> (d0, d1)>],228       iterator_types = ["parallel", "parallel"]}229      ins(%in1, %in3: tensor<2xf32>, tensor<2x3xf32>) outs(%out2: tensor<2x3xf32>) {230        ^bb0(%arg0: f32, %arg1: f32, %arg3: f32):231          %0 = arith.addf %arg0, %arg1 : f32232          linalg.yield %0 : f32233      } -> tensor<2x3xf32>234    return %add, %add_bcast, %non_elementwise : tensor<2xf32>, tensor<2x3xf32>, tensor<2x3xf32>235  }236}237 238// -----239 240module attributes { transform.with_named_sequence } {241  transform.named_sequence @print_reduction(%arg0: !transform.any_op {transform.readonly}) {242    transform.debug.emit_remark_at %arg0, "reduction" : !transform.any_op243    transform.yield244  }245 246  transform.named_sequence @match_structured_body_reduction(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op {247    %0 = transform.match.structured failures(propagate) %arg0 : (!transform.any_op) -> !transform.any_op {248    ^bb0(%arg1: !transform.any_op):249      transform.match.structured.body %arg1 { reduction_position = 0 } : !transform.any_op250      transform.match.structured.yield %arg1 : !transform.any_op251    }252    transform.yield %0 : !transform.any_op253  }254 255  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {256    transform.foreach_match in %arg0257        @match_structured_body_reduction -> @print_reduction258        : (!transform.any_op) -> !transform.any_op259    transform.yield260  }261 262  func.func @payload(%lhs: tensor<2x4xf32>, %rhs: tensor<4x3xf32>, %out: tensor<2x3xf32>) attributes { transform.target_tag = "start_here" } {263    // expected-remark @below {{reduction}}264    linalg.generic {265      indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d2)>, affine_map<(d0, d1, d2) -> (d2, d1)>, affine_map<(d0, d1, d2) -> (d0, d1)>],266      iterator_types = ["parallel", "parallel", "reduction"]267    } ins(%lhs, %rhs: tensor<2x4xf32>, tensor<4x3xf32>) outs(%out: tensor<2x3xf32>) {268    ^bb0(%arg0: f32, %arg1: f32, %arg2: f32):269      %0 = arith.mulf %arg0, %arg1 : f32270      %1 = arith.addf %0, %arg2 : f32271      linalg.yield %1 : f32272    } -> tensor<2x3xf32>273 274    %r = tensor.empty() : tensor<2x3xf32>275    linalg.generic {276      indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d2)>, affine_map<(d0, d1, d2) -> (d2, d1)>,277                       affine_map<(d0, d1, d2) -> (d0, d1)>, affine_map<(d0, d1, d2) -> (d0, d1)>],278      iterator_types = ["parallel", "parallel", "reduction"]279    } ins(%lhs, %rhs: tensor<2x4xf32>, tensor<4x3xf32>) outs(%out, %r: tensor<2x3xf32>, tensor<2x3xf32>) {280    ^bb0(%arg0: f32, %arg1: f32, %arg2: f32, %arg3: f32):281      %0 = arith.mulf %arg0, %arg1 : f32282      %1 = arith.cmpf olt, %0, %arg2 : f32283      %2 = arith.select %1, %0, %arg2 : f32284      %3 = arith.select %1, %arg3, %0 : f32285      linalg.yield %2, %3 : f32, f32286    } -> (tensor<2x3xf32>, tensor<2x3xf32>)287 288    // expected-remark @below {{reduction}}289    linalg.matmul ins(%lhs, %rhs: tensor<2x4xf32>, tensor<4x3xf32>) outs(%out: tensor<2x3xf32>) -> tensor<2x3xf32>290 291    %e = tensor.empty() : tensor<2x4xf32>292    linalg.generic {293      indexing_maps = [affine_map<(d0, d1) -> (d0, d1)>, affine_map<(d0, d1) -> (d0, d1)>],294      iterator_types = ["parallel", "parallel"]295    } ins(%lhs: tensor<2x4xf32>) outs(%e: tensor<2x4xf32>) {296    ^bb0(%arg0: f32, %arg1: f32):297      linalg.yield %arg0 : f32298    } -> tensor<2x4xf32>299 300    return301  }302}303 304 305// -----306 307module attributes { transform.with_named_sequence } {308  transform.named_sequence @do_nothing(%arg0: !transform.any_op {transform.readonly}) {309    transform.yield310  }311 312  transform.named_sequence @print_dimension_size_match(%arg0: !transform.any_op {transform.readonly}) {313    transform.debug.emit_remark_at %arg0, "matched sizes" : !transform.any_op314    transform.yield315  }316 317  transform.named_sequence @match_dimension_capture(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op {318    // Capture multiple dimension values. Suppress failures so we can print them anyway after the capture.319    %0:9 = transform.match.structured failures(suppress) %arg0320      : (!transform.any_op) -> (!transform.any_op, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>,321            !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>) {322    ^bb0(%arg1: !transform.any_op):323      // This also tests the positional specification used by other ops, which may not test it again.324      %1 = transform.match.structured.dim %arg1[all] : (!transform.any_op) -> !transform.param<i64>325      %2 = transform.match.structured.dim %arg1[0] : (!transform.any_op) -> !transform.param<i64>326      %3 = transform.match.structured.dim %arg1[-1] : (!transform.any_op) -> !transform.param<i64>327      %4 = transform.match.structured.dim %arg1[0, 2] : (!transform.any_op) -> !transform.param<i64>328      %5 = transform.match.structured.dim %arg1[0, -1] : (!transform.any_op) -> !transform.param<i64>329      %6 = transform.match.structured.dim %arg1[except(-1)] : (!transform.any_op) -> !transform.param<i64>330      %7 = transform.match.structured.dim %arg1[except(0, -2)] : (!transform.any_op) -> !transform.param<i64>331      %8 = transform.match.structured.dim %arg1[0, -3] : (!transform.any_op) -> !transform.param<i64>332      transform.match.structured.yield %arg1, %1, %2, %3, %4, %5, %6, %7, %8333          : !transform.any_op, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>,334            !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>335    }336    transform.debug.emit_param_as_remark %0#1, "dimensions all:" at %0#0 : !transform.param<i64>, !transform.any_op337    transform.debug.emit_param_as_remark %0#2, "dimension 0:" at %0#0 : !transform.param<i64>, !transform.any_op338    transform.debug.emit_param_as_remark %0#3, "dimension -1:" at %0#0 : !transform.param<i64>, !transform.any_op339    transform.debug.emit_param_as_remark %0#4, "dimensions 0, 2:" at %0#0 : !transform.param<i64>, !transform.any_op340    transform.debug.emit_param_as_remark %0#5, "dimensions 0, -1:" at %0#0 : !transform.param<i64>, !transform.any_op341    transform.debug.emit_param_as_remark %0#6, "dimensions except -1:" at %0#0 : !transform.param<i64>, !transform.any_op342    transform.debug.emit_param_as_remark %0#7, "dimensions except 0, -2:" at %0#0 : !transform.param<i64>, !transform.any_op343    transform.debug.emit_param_as_remark %0#8, "dimensions 0, -3:" at %0#0 : !transform.param<i64>, !transform.any_op344    transform.yield %0#0 : !transform.any_op345  }346 347  transform.named_sequence @match_dimension_sizes(%arg0: !transform.any_op {transform.readonly}) -> (!transform.any_op) {348    %0 = transform.match.structured failures(propagate) %arg0 : (!transform.any_op) -> !transform.any_op {349    ^bb0(%arg1: !transform.any_op):350      %1 = transform.match.structured.dim %arg1[all] : (!transform.any_op) -> !transform.param<i64>351      %c2 = transform.param.constant 2 : i64 -> !transform.param<i64>352      %c3 = transform.param.constant 3 : i64 -> !transform.param<i64>353      %c4 = transform.param.constant 4 : i64 -> !transform.param<i64>354      %2 = transform.merge_handles %c2, %c3, %c4 : !transform.param<i64>355      transform.match.param.cmpi eq %1, %2 : !transform.param<i64>356 357      transform.match.structured.yield %arg1 : !transform.any_op358    }359    transform.yield %0 : !transform.any_op360  }361 362  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {363    %0 = transform.foreach_match in %arg0 @match_dimension_capture -> @do_nothing : (!transform.any_op) -> !transform.any_op364    %1 = transform.foreach_match in %0 @match_dimension_sizes -> @print_dimension_size_match : (!transform.any_op) -> !transform.any_op365    transform.yield366  }367 368  func.func @payload(%lhs: tensor<2x4xf32>, %rhs: tensor<4x3xf32>, %out: tensor<2x3xf32>) attributes { transform.target_tag = "start_here" } {369    // The last does not emit anything because it fails to match370    // due to 0 and -3 being the same dimension in the 3D case.371    // expected-remark @below {{dimensions all: 2 : i64, 3 : i64, 4 : i64}}372    // expected-remark @below {{dimension 0: 2 : i64}}373    // expected-remark @below {{dimension -1: 4 : i64}}374    // expected-remark @below {{dimensions 0, 2: 2 : i64, 4 : i64}}375    // expected-remark @below {{dimensions 0, -1: 2 : i64, 4 : i64}}376    // expected-remark @below {{dimensions except -1: 2 : i64, 3 : i64}}377    // expected-remark @below {{dimensions except 0, -2: 4 : i64}}378    // expected-remark @below {{dimensions 0, -3:}}379    // expected-remark @below {{matched sizes}}380    linalg.generic {381      indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d2)>, affine_map<(d0, d1, d2) -> (d2, d1)>, affine_map<(d0, d1, d2) -> (d0, d1)>],382      iterator_types = ["parallel", "parallel", "reduction"]383    } ins(%lhs, %rhs: tensor<2x4xf32>, tensor<4x3xf32>) outs(%out: tensor<2x3xf32>) {384    ^bb0(%arg0: f32, %arg1: f32, %arg2: f32):385      %0 = arith.mulf %arg0, %arg1 : f32386      %1 = arith.addf %0, %arg2 : f32387      linalg.yield %1 : f32388    } -> tensor<2x3xf32>389 390    return391  }392}393 394// -----395 396module attributes { transform.with_named_sequence } {397  transform.named_sequence @print_all_reduction(%arg0: !transform.any_op {transform.readonly}) {398    transform.debug.emit_remark_at %arg0, "all reduction" : !transform.any_op399    transform.yield400  }401  transform.named_sequence @print_all_parallel(%arg0: !transform.any_op {transform.readonly}) {402    transform.debug.emit_remark_at %arg0, "all parallel" : !transform.any_op403    transform.yield404  }405  transform.named_sequence @print_last_reduction(%arg0: !transform.any_op {transform.readonly}) {406    transform.debug.emit_remark_at %arg0, "last reduction" : !transform.any_op407    transform.yield408  }409  transform.named_sequence @print_parallel_except_last(%arg0: !transform.any_op {transform.readonly}) {410    transform.debug.emit_remark_at %arg0, "parallel except last" : !transform.any_op411    transform.yield412  }413 414  transform.named_sequence @match_all_reduction(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op {415    transform.match.structured failures(propagate) %arg0 : !transform.any_op {416    ^bb0(%arg1: !transform.any_op):417      transform.match.structured.dim %arg1[all] { reduction } : !transform.any_op418      transform.match.structured.yield419    }420    transform.yield %arg0 : !transform.any_op421  }422  transform.named_sequence @match_all_parallel(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op {423    transform.match.structured failures(propagate) %arg0 : !transform.any_op {424    ^bb0(%arg1: !transform.any_op):425      transform.match.structured.dim %arg1[all] { parallel } : !transform.any_op426      transform.match.structured.yield427    }428    transform.yield %arg0 : !transform.any_op429  }430  transform.named_sequence @match_last_reduction(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op {431    transform.match.structured failures(propagate) %arg0 : !transform.any_op {432    ^bb0(%arg1: !transform.any_op):433      transform.match.structured.dim %arg1[-1] { reduction } : !transform.any_op434      transform.match.structured.yield435    }436    transform.yield %arg0 : !transform.any_op437  }438  transform.named_sequence @match_parallel_except_last(%arg0: !transform.any_op {transform.readonly}) -> !transform.any_op {439    transform.match.structured failures(propagate) %arg0 : !transform.any_op {440    ^bb0(%arg1: !transform.any_op):441      transform.match.structured.dim %arg1[except(-1)] { parallel } : !transform.any_op442      transform.match.structured.yield443    }444    transform.yield %arg0 : !transform.any_op445  }446 447  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {448    %0 = transform.foreach_match in %arg0 @match_all_reduction -> @print_all_reduction : (!transform.any_op) -> !transform.any_op449    %1 = transform.foreach_match in %0 @match_all_parallel -> @print_all_parallel : (!transform.any_op) -> !transform.any_op450    %2 = transform.foreach_match in %1 @match_last_reduction -> @print_last_reduction : (!transform.any_op) -> !transform.any_op451    %3 = transform.foreach_match in %2 @match_parallel_except_last -> @print_parallel_except_last : (!transform.any_op) -> !transform.any_op452    transform.yield453  }454 455  func.func @payload(%lhs: tensor<2x4xf32>, %rhs: tensor<4x3xf32>, %out: tensor<2x3xf32>) attributes { transform.target_tag = "start_here" } {456    // expected-remark @below {{last reduction}}457    // expected-remark @below {{parallel except last}}458    linalg.generic {459      indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d2)>, affine_map<(d0, d1, d2) -> (d2, d1)>, affine_map<(d0, d1, d2) -> (d0, d1)>],460      iterator_types = ["parallel", "parallel", "reduction"]461    } ins(%lhs, %rhs: tensor<2x4xf32>, tensor<4x3xf32>) outs(%out: tensor<2x3xf32>) {462    ^bb0(%arg0: f32, %arg1: f32, %arg2: f32):463      %0 = arith.mulf %arg0, %arg1 : f32464      %1 = arith.addf %0, %arg2 : f32465      linalg.yield %1 : f32466    } -> tensor<2x3xf32>467 468    // expected-remark @below {{last reduction}}469    // expected-remark @below {{parallel except last}}470    linalg.matmul ins(%lhs, %rhs : tensor<2x4xf32>, tensor<4x3xf32>) outs(%out : tensor<2x3xf32>) -> tensor<2x3xf32>471 472    %cst = arith.constant 1.0 : f32473    // expected-remark @below {{all parallel}}474    // expected-remark @below {{parallel except last}}475    linalg.fill ins(%cst : f32) outs(%out: tensor<2x3xf32>) -> tensor<2x3xf32>476 477    return478  }479}480 481// -----482 483module attributes { transform.with_named_sequence } {484  transform.named_sequence @match_bitwidth(%arg0: !transform.any_op {transform.readonly}) -> (!transform.any_op, !transform.param<i64>) {485    %bw = transform.match.structured failures(propagate) %arg0 : (!transform.any_op) -> !transform.param<i64> {486    ^bb0(%arg1: !transform.any_op):487      %0 = transform.match.structured.init %arg1 [0] : (!transform.any_op) -> !transform.any_value488      %1 = transform.match.structured.elemental_bitwidth %0 : (!transform.any_value) -> !transform.param<i64>489      transform.match.structured.yield %1 : !transform.param<i64>490    }491    transform.yield %arg0, %bw : !transform.any_op, !transform.param<i64>492  }493 494  transform.named_sequence @print_bitwidth(%arg0: !transform.any_op {transform.readonly}, %arg1: !transform.param<i64> {transform.readonly}) {495    transform.debug.emit_param_as_remark %arg1, "bitwidth:" at %arg0 : !transform.param<i64>, !transform.any_op496    transform.yield497  }498 499  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {500    transform.foreach_match in %arg0 @match_bitwidth -> @print_bitwidth : (!transform.any_op) -> !transform.any_op501    transform.yield502  }503 504  func.func @payload(%f32: f32, %tf32: tensor<?xf32>,505                     %index: index, %tindex: tensor<?xindex>)506            attributes { transform.target_tag = "start_here" }  {507    // expected-remark @below {{bitwidth: 32}}508    linalg.fill ins(%f32: f32) outs(%tf32: tensor<?xf32>) -> tensor<?xf32>509    linalg.fill ins(%index: index) outs(%tindex: tensor<?xindex>) -> tensor<?xindex>510    return511  }512}513 514// -----515 516module attributes { transform.with_named_sequence } {517  transform.named_sequence @match_init(%arg0: !transform.any_op {transform.readonly})518      -> (!transform.any_op, !transform.any_value, !transform.any_value, !transform.any_op) {519    %outs:3 = transform.match.structured failures(suppress) %arg0520      : (!transform.any_op) -> (!transform.any_value, !transform.any_value, !transform.any_op) {521    ^bb0(%arg1: !transform.any_op):522      %0 = transform.match.structured.init %arg1 [0] : (!transform.any_op) -> !transform.any_value523      %1 = transform.match.structured.init %arg1 [all] : (!transform.any_op) -> !transform.any_value524      %2 = transform.match.structured.init %arg1 [0] : (!transform.any_op) -> !transform.any_op525      transform.match.structured.yield %0, %1, %2 : !transform.any_value, !transform.any_value, !transform.any_op526    }527    transform.yield %arg0, %outs#0, %outs#1, %outs#2 : !transform.any_op, !transform.any_value, !transform.any_value, !transform.any_op528  }529 530  transform.named_sequence @print_init(%arg0: !transform.any_op {transform.readonly},531                                         %arg1: !transform.any_value {transform.readonly},532                                         %arg2: !transform.any_value {transform.readonly},533                                         %arg3: !transform.any_op {transform.readonly}) {534    transform.debug.emit_remark_at %arg1, "output 0" : !transform.any_value535    transform.debug.emit_remark_at %arg3, "output producer" : !transform.any_op536    transform.debug.emit_remark_at %arg2, "all output" : !transform.any_value537    transform.yield538  }539 540  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {541    transform.foreach_match in %arg0 @match_init -> @print_init : (!transform.any_op) -> !transform.any_op542    transform.yield543  }544 545 546  func.func @payload(%f32: f32,547            // expected-remark @below {{output 0}}548            // expected-remark @below {{all output}}549            // expected-note @below {{value handle points to a block argument #1 in block #0 in region #0}}550            %tf32: tensor<?xf32>,551            // expected-remark @below {{all output}}552            // expected-note @below {{value handle points to a block argument #2 in block #0 in region #0}}553            %tf32_2: tensor<?xf32>)554            attributes { transform.target_tag = "start_here" }  {555    // expected-remark @below {{output 0}}556    // expected-remark @below {{output producer}}557    // expected-remark @below {{all output}}558    // expected-note @below {{value handle points to an op result #0}}559    %0 = linalg.fill ins(%f32: f32) outs(%tf32: tensor<?xf32>) -> tensor<?xf32>560 561    linalg.generic {562      indexing_maps = [affine_map<(d0) -> (d0)>, affine_map<(d0) -> (d0)>, affine_map<(d0) -> (d0)>],563      iterator_types = ["parallel"]564    } ins(%tf32: tensor<?xf32>) outs(%0, %tf32_2: tensor<?xf32>, tensor<?xf32>) {565    ^bb0(%arg0: f32, %arg1: f32, %arg2: f32):566      linalg.yield %arg0, %arg0 : f32, f32567    } -> (tensor<?xf32>, tensor<?xf32>)568    return569  }570}571 572// -----573 574module attributes { transform.with_named_sequence } {575  transform.named_sequence @match_init_0_permutation(%arg0: !transform.any_op {transform.readonly})576      -> !transform.any_op {577    %0 = transform.match.structured failures(propagate) %arg0 : (!transform.any_op) -> !transform.any_op {578    ^bb0(%arg1: !transform.any_op):579      transform.match.structured.init %arg1[0] { permutation }: !transform.any_op580      transform.match.structured.yield %arg1 : !transform.any_op581    }582    transform.yield %0 : !transform.any_op583  }584  transform.named_sequence @match_init_1_permutation(%arg0: !transform.any_op {transform.readonly})585      -> !transform.any_op {586    %0 = transform.match.structured failures(propagate) %arg0 : (!transform.any_op) -> !transform.any_op {587    ^bb0(%arg1: !transform.any_op):588      transform.match.structured.init %arg1[1] { permutation }: !transform.any_op589      transform.match.structured.yield %arg1 : !transform.any_op590    }591    transform.yield %0 : !transform.any_op592  }593  transform.named_sequence @match_init_2_projected_permutation(%arg0: !transform.any_op {transform.readonly})594      -> !transform.any_op {595    %0 = transform.match.structured failures(propagate) %arg0 : (!transform.any_op) -> !transform.any_op {596    ^bb0(%arg1: !transform.any_op):597      transform.match.structured.init %arg1[2] { projected_permutation }: !transform.any_op598      transform.match.structured.yield %arg1 : !transform.any_op599    }600    transform.yield %0 : !transform.any_op601  }602 603  transform.named_sequence @print_init_0_permutation(%arg0: !transform.any_op {transform.readonly}) {604    transform.debug.emit_remark_at %arg0, "matched output 0 permutation" : !transform.any_op605    transform.yield606  }607  transform.named_sequence @print_init_1_permutation(%arg0: !transform.any_op {transform.readonly}) {608    transform.debug.emit_remark_at %arg0, "matched output 1 permutation" : !transform.any_op609    transform.yield610  }611  transform.named_sequence @print_init_2_projected_permutation(%arg0: !transform.any_op {transform.readonly}) {612    transform.debug.emit_remark_at %arg0, "matched output 2 projected permutation" : !transform.any_op613    transform.yield614  }615 616  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {617    %0 = transform.foreach_match in %arg0 @match_init_0_permutation -> @print_init_0_permutation : (!transform.any_op) -> !transform.any_op618    %1 = transform.foreach_match in %0 @match_init_1_permutation -> @print_init_1_permutation : (!transform.any_op) -> !transform.any_op619    %2 = transform.foreach_match in %1 @match_init_2_projected_permutation -> @print_init_2_projected_permutation : (!transform.any_op) -> !transform.any_op620    transform.yield621  }622 623  func.func @payload(%f32: f32,624            %oned: tensor<?xf32>,625            %oned2: tensor<?xf32>,626            %twod: tensor<?x?xf32>)627            attributes { transform.target_tag = "start_here" }  {628    // expected-remark @below {{matched output 2 projected permutation}}629    linalg.generic {630      indexing_maps = [affine_map<(d0, d1) -> (d0)>,631                       affine_map<(d0, d1) -> (d0 + d1)>,632                       affine_map<(d0, d1) -> (d1)>,633                       affine_map<(d0, d1) -> (d1, d0)>],634      iterator_types = ["parallel", "parallel"]635    } ins(%oned: tensor<?xf32>) outs(%oned, %oned2, %twod: tensor<?xf32>, tensor<?xf32>, tensor<?x?xf32>) {636    ^bb0(%arg0: f32, %arg1: f32, %arg2: f32, %arg3: f32):637      linalg.yield %arg0, %arg0, %arg0 : f32, f32, f32638    } -> (tensor<?xf32>, tensor<?xf32>, tensor<?x?xf32>)639 640    // expected-remark @below {{matched output 2 projected permutation}}641    // expected-remark @below {{matched output 1 permutation}}642    linalg.generic {643      indexing_maps = [affine_map<(d0, d1) -> (d0)>,644                       affine_map<(d0, d1) -> (d0 + d1)>,645                       affine_map<(d0, d1) -> (d1, d0)>,646                       affine_map<(d0, d1) -> (d1)>],647      iterator_types = ["parallel", "parallel"]648    } ins(%oned: tensor<?xf32>) outs(%oned, %twod, %oned2: tensor<?xf32>, tensor<?x?xf32>, tensor<?xf32>) {649    ^bb0(%arg0: f32, %arg1: f32, %arg2: f32, %arg3: f32):650      linalg.yield %arg0, %arg0, %arg0 : f32, f32, f32651    } -> (tensor<?xf32>,  tensor<?x?xf32>, tensor<?xf32>)652    return653  }654}655 656// -----657 658 659 660module attributes { transform.with_named_sequence } {661  transform.named_sequence @match_num_io(%arg0: !transform.any_op {transform.readonly})662      -> (!transform.param<i64>, !transform.param<i64>, !transform.any_op) {663    %0:3 = transform.match.structured failures(propagate) %arg0664         : (!transform.any_op) -> (!transform.param<i64>, !transform.param<i64>, !transform.any_op) {665    ^bb0(%arg1: !transform.any_op):666      %1 = transform.match.structured.num_inputs %arg1 : (!transform.any_op) -> !transform.param<i64>667      %2 = transform.match.structured.num_inits %arg1 : (!transform.any_op) -> !transform.param<i64>668      transform.match.structured.yield %1, %2, %arg1 : !transform.param<i64>, !transform.param<i64>, !transform.any_op669    }670    transform.yield %0#0, %0#1, %0#2 : !transform.param<i64>, !transform.param<i64>, !transform.any_op671  }672 673 674  transform.named_sequence @print_num_io(675      %arg0: !transform.param<i64> {transform.readonly},676      %arg1: !transform.param<i64> {transform.readonly},677      %arg2: !transform.any_op {transform.readonly}) {678    transform.debug.emit_param_as_remark %arg0, "inputs" at %arg2 : !transform.param<i64>, !transform.any_op679    transform.debug.emit_param_as_remark %arg1, "outputs" at %arg2 : !transform.param<i64>, !transform.any_op680    transform.yield681  }682 683 684  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {685    %0 = transform.foreach_match in %arg0 @match_num_io -> @print_num_io : (!transform.any_op) -> !transform.any_op686    transform.yield687  }688 689  func.func @payload(%f32: f32,690            %oned: tensor<?xf32>,691            %oned2: tensor<?xf32>,692            %twod: tensor<?x?xf32>)693            attributes { transform.target_tag = "start_here" }  {694    // expected-remark @below {{inputs 1}}695    // expected-remark @below {{outputs 3}}696    linalg.generic {697      indexing_maps = [affine_map<(d0, d1) -> (d0)>,698                       affine_map<(d0, d1) -> (d0 + d1)>,699                       affine_map<(d0, d1) -> (d1)>,700                       affine_map<(d0, d1) -> (d1, d0)>],701      iterator_types = ["parallel", "parallel"]702    } ins(%oned: tensor<?xf32>) outs(%oned, %oned2, %twod: tensor<?xf32>, tensor<?xf32>, tensor<?x?xf32>) {703    ^bb0(%arg0: f32, %arg1: f32, %arg2: f32, %arg3: f32):704      linalg.yield %arg0, %arg0, %arg0 : f32, f32, f32705    } -> (tensor<?xf32>, tensor<?xf32>, tensor<?x?xf32>)706 707    // expected-remark @below {{inputs 2}}708    // expected-remark @below {{outputs 2}}709    linalg.generic {710      indexing_maps = [affine_map<(d0, d1) -> (d0)>,711                       affine_map<(d0, d1) -> (d1, d0)>,712                       affine_map<(d0, d1) -> (d0 + d1)>,713                       affine_map<(d0, d1) -> (d1)>],714      iterator_types = ["parallel", "parallel"]715    } ins(%oned, %twod: tensor<?xf32>, tensor<?x?xf32>) outs(%oned, %oned2: tensor<?xf32>, tensor<?xf32>) {716    ^bb0(%arg0: f32, %arg1: f32, %arg2: f32, %arg3: f32):717      linalg.yield %arg0, %arg0 : f32, f32718    } -> (tensor<?xf32>, tensor<?xf32>)719    return720  }721}722 723// -----724 725module attributes { transform.with_named_sequence } {726  transform.named_sequence @match_rank(%arg0: !transform.any_op {transform.readonly})727      -> (!transform.param<i64>, !transform.any_op) {728    %0:2 = transform.match.structured failures(propagate) %arg0729         : (!transform.any_op) -> (!transform.param<i64>, !transform.any_op) {730    ^bb0(%arg1: !transform.any_op):731      %1 = transform.match.structured.rank %arg1 : (!transform.any_op) -> !transform.param<i64>732      transform.match.structured.yield %1, %arg1 : !transform.param<i64>, !transform.any_op733    }734    transform.yield %0#0, %0#1 : !transform.param<i64>, !transform.any_op735  }736 737 738  transform.named_sequence @print_rank(%arg0: !transform.param<i64> {transform.readonly},739                                       %arg2: !transform.any_op {transform.readonly}) {740    transform.debug.emit_param_as_remark %arg0, "rank" at %arg2 : !transform.param<i64>, !transform.any_op741    transform.yield742  }743 744  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {745    %0 = transform.foreach_match in %arg0 @match_rank -> @print_rank : (!transform.any_op) -> !transform.any_op746    transform.yield747  }748 749  func.func @payload(%f32: f32,750            %twod: tensor<42x42xf32>)751            attributes { transform.target_tag = "start_here" } {752    %0 = tensor.empty() : tensor<42x42xf32>753    // expected-remark @below {{rank 2}}754    %1 = linalg.fill ins(%f32 : f32) outs(%0 : tensor<42x42xf32>) -> tensor<42x42xf32>755    // expected-remark @below {{rank 3}}756    linalg.matmul ins(%twod, %twod : tensor<42x42xf32>, tensor<42x42xf32>)757                  outs(%1 : tensor<42x42xf32>) -> tensor<42x42xf32>758    return759  }760}761 762// -----763 764module attributes { transform.with_named_sequence } {765  transform.named_sequence @match_single_result(%arg0: !transform.any_op {transform.readonly})766      -> (!transform.any_op, !transform.any_op) {767    %0:2 = transform.match.structured failures(propagate) %arg0768         : (!transform.any_op) -> (!transform.any_op, !transform.any_op) {769    ^bb0(%arg1: !transform.any_op):770      %1 = transform.match.structured.result %arg1[0] { single } : (!transform.any_op) -> !transform.any_op771      transform.match.structured.yield %1, %arg1 : !transform.any_op, !transform.any_op772    }773    transform.yield %0#0, %0#1 : !transform.any_op, !transform.any_op774  }775  transform.named_sequence @match_result_value(%arg0: !transform.any_op {transform.readonly})776      -> (!transform.any_value, !transform.any_op) {777    %0:2 = transform.match.structured failures(propagate) %arg0778         : (!transform.any_op) -> (!transform.any_value, !transform.any_op) {779    ^bb0(%arg1: !transform.any_op):780      %1 = transform.match.structured.result %arg1[0] : (!transform.any_op) -> !transform.any_value781      transform.match.structured.yield %1, %arg1 : !transform.any_value, !transform.any_op782    }783    transform.yield %0#0, %0#1 : !transform.any_value, !transform.any_op784  }785  transform.named_sequence @match_any_result(%arg0: !transform.any_op {transform.readonly})786      -> (!transform.any_op) {787    %0 = transform.match.structured failures(propagate) %arg0788         : (!transform.any_op) -> !transform.any_op {789    ^bb0(%arg1: !transform.any_op):790      %1 = transform.match.structured.result %arg1[-1] { any } : (!transform.any_op) -> !transform.any_op791      transform.match.structured.yield %arg1 : !transform.any_op792    }793    transform.yield %0 : !transform.any_op794  }795 796  transform.named_sequence @print_single_result(%arg0: !transform.any_op {transform.readonly},797                                                %arg2: !transform.any_op {transform.readonly}) {798    transform.debug.emit_remark_at %arg2, "matched single result" : !transform.any_op799    transform.debug.emit_remark_at %arg0, "single user" : !transform.any_op800    transform.yield801  }802  transform.named_sequence @print_result_value(%arg0: !transform.any_value {transform.readonly},803                                               %arg1: !transform.any_op {transform.readonly}) {804    transform.debug.emit_remark_at %arg1, "matched result value" : !transform.any_op805    transform.debug.emit_remark_at %arg0, "op result" : !transform.any_value806    transform.yield807  }808  transform.named_sequence @print_any_result(%arg0: !transform.any_op {transform.readonly}) {809    transform.debug.emit_remark_at %arg0, "matched any result" : !transform.any_op810    transform.yield811  }812 813  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {814    %0 = transform.foreach_match in %arg0 @match_single_result -> @print_single_result : (!transform.any_op) -> !transform.any_op815    %1 = transform.foreach_match in %0 @match_result_value -> @print_result_value : (!transform.any_op) -> !transform.any_op816    %2 = transform.foreach_match in %1 @match_any_result -> @print_any_result : (!transform.any_op) -> !transform.any_op817    transform.yield818  }819 820  func.func @payload(%f32: f32, %f322: f32, %f323: f32,821            %twod: tensor<42x42xf32>)822            attributes { transform.target_tag = "start_here" } {823    %0 = tensor.empty() : tensor<42x42xf32>824 825    // expected-remark @below {{matched result value}}826    // expected-remark @below {{op result}}827    // expected-note @below {{value handle points to an op result #0}}828    %1 = linalg.fill ins(%f32 : f32) outs(%0 : tensor<42x42xf32>) -> tensor<42x42xf32>829    // expected-remark @below {{matched result value}}830    // expected-remark @below {{op result}}831    // expected-note @below {{value handle points to an op result #0}}832    // expected-remark @below {{matched single result}}833    // expected-remark @below {{matched any result}}834    %2 = linalg.fill ins(%f322 : f32) outs(%0 : tensor<42x42xf32>) -> tensor<42x42xf32>835    // expected-remark @below {{matched result value}}836    // expected-remark @below {{op result}}837    // expected-note @below {{value handle points to an op result #0}}838    // expected-remark @below {{matched any result}}839    %3 = linalg.fill ins(%f323 : f32) outs(%0 : tensor<42x42xf32>) -> tensor<42x42xf32>840 841    // expected-remark @below {{matched result value}}842    // expected-remark @below {{op result}}843    // expected-note @below {{value handle points to an op result #0}}844    // expected-remark @below {{single user}}845    linalg.negf ins(%2 : tensor<42x42xf32>) outs(%0 : tensor<42x42xf32>) -> tensor<42x42xf32>846    // expected-remark @below {{matched result value}}847    // expected-remark @below {{op result}}848    // expected-note @below {{value handle points to an op result #0}}849    linalg.exp ins(%3 : tensor<42x42xf32>) outs(%0 : tensor<42x42xf32>) -> tensor<42x42xf32>850    // expected-remark @below {{matched result value}}851    // expected-remark @below {{op result}}852    // expected-note @below {{value handle points to an op result #0}}853    linalg.exp ins(%3 : tensor<42x42xf32>) outs(%0 : tensor<42x42xf32>) -> tensor<42x42xf32>854    return855  }856}857 858// -----859 860module attributes { transform.with_named_sequence } {861  transform.named_sequence @match_input_indexing_map(%arg0: !transform.any_op {transform.readonly})862      -> (!transform.affine_map, !transform.any_op) {863    %0 = transform.match.structured failures(propagate) %arg0864         : (!transform.any_op) -> !transform.affine_map {865    ^bb0(%arg1: !transform.any_op):866      %1 = transform.match.structured.input %arg1[0]  : (!transform.any_op) -> !transform.affine_map867      transform.match.structured.yield %1 : !transform.affine_map868    }869    transform.yield %0, %arg0 : !transform.affine_map, !transform.any_op870  }871  transform.named_sequence @match_init_indexing_map(%arg0: !transform.any_op {transform.readonly})872      -> (!transform.affine_map, !transform.any_op) {873    %0 = transform.match.structured failures(propagate) %arg0874         : (!transform.any_op) -> !transform.affine_map {875    ^bb0(%arg1: !transform.any_op):876      %1 = transform.match.structured.init %arg1[0]  : (!transform.any_op) -> !transform.affine_map877      transform.match.structured.yield %1 : !transform.affine_map878    }879    transform.yield %0, %arg0 : !transform.affine_map, !transform.any_op880  }881 882  transform.named_sequence @print_indexing_map_1(%arg0: !transform.affine_map {transform.readonly},883                                               %arg1: !transform.any_op {transform.readonly}) {884    transform.debug.emit_param_as_remark %arg0, "indexing map 1" at %arg1 : !transform.affine_map, !transform.any_op885    transform.yield886  }887  transform.named_sequence @print_indexing_map_2(%arg0: !transform.affine_map {transform.readonly},888                                               %arg1: !transform.any_op {transform.readonly}) {889    transform.debug.emit_param_as_remark %arg0, "indexing map 2" at %arg1 : !transform.affine_map, !transform.any_op890    transform.yield891  }892 893  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {894    %3 = transform.foreach_match in %arg0 @match_input_indexing_map -> @print_indexing_map_1 : (!transform.any_op) -> !transform.any_op895    %4 = transform.foreach_match in %3 @match_init_indexing_map -> @print_indexing_map_2 : (!transform.any_op) -> !transform.any_op896    transform.yield897  }898 899  func.func @payload(%lhs: tensor<32x32xf32>, %rhs: tensor<32x32xf32>)900            attributes { transform.target_tag = "start_here" } {901    %out = tensor.empty() : tensor<32x32xf32>902    %cst = arith.constant 1.0 : f32903    // expected-remark @below {{indexing map 1 affine_map<(d0, d1) -> ()>}}904    // expected-remark @below {{indexing map 2 affine_map<(d0, d1) -> (d0, d1)>}}905    %res = linalg.fill ins(%cst : f32) outs(%out : tensor<32x32xf32>) -> tensor<32x32xf32>906    // expected-remark @below {{indexing map 1 affine_map<(d0, d1, d2) -> (d0, d2)>}}907    // expected-remark @below {{indexing map 2 affine_map<(d0, d1, d2) -> (d0, d1)>}}908    linalg.matmul ins(%lhs, %rhs : tensor<32x32xf32>, tensor<32x32xf32>) outs(%res : tensor<32x32xf32>) -> tensor<32x32xf32>909    return910  }911}912 913// -----914 915module attributes { transform.with_named_sequence } {916  transform.named_sequence @match_contraction(%arg0: !transform.any_op {transform.readonly})917    -> (!transform.any_op, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>) {918    %1:4 = transform.match.structured %arg0 : (!transform.any_op) -> (!transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>) {919    ^bb0(%struct: !transform.any_op):920      transform.match.structured.body %struct { contraction = ["arith.mulf", "arith.addf"] } : !transform.any_op921      %0:4 = transform.match.structured.classify_contraction_dims %struct922        : (!transform.any_op) -> (!transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>)923      transform.match.structured.yield %0#0, %0#1, %0#2, %0#3924        : !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>925    }926    transform.yield %arg0, %1#0, %1#1, %1#2, %1#3 : !transform.any_op, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>927  }928 929  transform.named_sequence @print_contraction(930      %op: !transform.any_op {transform.readonly},931      %batch: !transform.param<i64> {transform.readonly},932      %m: !transform.param<i64> {transform.readonly},933      %n: !transform.param<i64> {transform.readonly},934      %k: !transform.param<i64> {transform.readonly}) {935    transform.debug.emit_remark_at %op, "contraction" : !transform.any_op936    transform.debug.emit_param_as_remark %batch, "batch dims" at %op : !transform.param<i64>, !transform.any_op937    transform.debug.emit_param_as_remark %m, "m dims" at %op : !transform.param<i64>, !transform.any_op938    transform.debug.emit_param_as_remark %n, "n dims" at %op : !transform.param<i64>, !transform.any_op939    transform.debug.emit_param_as_remark %k, "k dims" at %op : !transform.param<i64>, !transform.any_op940    transform.yield941  }942 943  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {944    %3 = transform.foreach_match in %arg0 @match_contraction -> @print_contraction : (!transform.any_op) -> !transform.any_op945    transform.yield946  }947}948 949module attributes { transform.target_tag = "start_here" } {950  func.func @matmul_simple(%lhs: tensor<10x20xf32>, %rhs: tensor<20x15xf32>) -> tensor<10x15xf64> {951    %cst = arith.constant 0.0 : f64952    %empty = tensor.empty() : tensor<10x15xf64>953    %fill = linalg.fill ins(%cst : f64) outs(%empty : tensor<10x15xf64>) -> tensor<10x15xf64>954    // expected-remark @below {{contraction}}955    // expected-remark @below {{batch dims}}956    // expected-remark @below {{m dims 0}}957    // expected-remark @below {{n dims 1}}958    // expected-remark @below {{k dims 2}}959    %result = linalg.matmul ins(%lhs, %rhs: tensor<10x20xf32>, tensor<20x15xf32>) outs(%fill: tensor<10x15xf64>) -> tensor<10x15xf64>960    return %result : tensor<10x15xf64>961  }962 963  func.func @vecmat_simple(%lhs: tensor<20xf32>, %rhs: tensor<20x15xf32>) -> tensor<15xf64> {964    %cst = arith.constant 0.0 : f64965    %empty = tensor.empty() : tensor<15xf64>966    %fill = linalg.fill ins(%cst : f64) outs(%empty : tensor<15xf64>) -> tensor<15xf64>967    // expected-remark @below {{contraction}}968    // expected-remark @below {{batch dims}}969    // expected-remark @below {{m dims}}970    // expected-remark @below {{n dims 0}}971    // expected-remark @below {{k dims 1}}972    %result = linalg.vecmat ins(%lhs, %rhs: tensor<20xf32>, tensor<20x15xf32>) outs(%fill: tensor<15xf64>) -> tensor<15xf64>973    return %result : tensor<15xf64>974  }975 976  func.func @double_batch(%lhs: tensor<40x10x50x20xf32>, %rhs: tensor<40x20x50x15xf32>) -> tensor<40x10x50x15xf32> {977    %cst = arith.constant 0.0 : f32978    %empty = tensor.empty() : tensor<40x10x50x15xf32>979    %fill = linalg.fill ins(%cst : f32) outs(%empty : tensor<40x10x50x15xf32>) -> tensor<40x10x50x15xf32>980    // expected-remark @below {{contraction}}981    // expected-remark @below {{batch dims 0 : i64, 2 : i64}}982    // expected-remark @below {{m dims 1}}983    // expected-remark @below {{n dims 3}}984    // expected-remark @below {{k dims 4}}985    %result = linalg.generic {986      indexing_maps = [affine_map<(d0, d1, d2, d3, d4) -> (d0, d1, d2, d4)>,987                      affine_map<(d0, d1, d2, d3, d4) -> (d0, d4, d2, d3)>,988                      affine_map<(d0, d1, d2, d3, d4) -> (d0, d1, d2, d3)>],989      iterator_types = ["parallel", "parallel", "parallel", "parallel", "reduction"]990    } ins(%lhs, %rhs : tensor<40x10x50x20xf32>, tensor<40x20x50x15xf32>)991      outs(%fill : tensor<40x10x50x15xf32>) {992    ^bb(%arg0: f32, %arg1: f32, %arg2: f32):993      %0 = arith.mulf %arg0, %arg1 : f32994      %1 = arith.addf %arg2, %0 : f32995      linalg.yield %1 : f32996    } -> tensor<40x10x50x15xf32>997    return %result : tensor<40x10x50x15xf32>998  }999 1000  func.func @generic_min(%arg0: tensor<1x7x4xf32>, %arg1: tensor<4xf32>, %arg2: tensor<1x1x4xf32>) {1001    linalg.generic {1002      indexing_maps = [affine_map<(d0, d1, d2, d3) -> (d0, d1 * 2 + d3 * 2, d2)>, 1003      affine_map<(d0, d1, d2, d3) -> (d3)>, 1004      affine_map<(d0, d1, d2, d3) -> (d0, d1, d2)>], 1005      iterator_types = ["parallel", "parallel", "parallel", "reduction"]} 1006      ins(%arg0, %arg1 : tensor<1x7x4xf32>, tensor<4xf32>) 1007      outs(%arg2 : tensor<1x1x4xf32>) {1008    ^bb0(%in: f32, %in_1: f32, %out: f32):1009      %5 = arith.minimumf %out, %in : f321010      linalg.yield %5 : f321011    } -> tensor<1x1x4xf32>1012    return1013  }1014 1015  func.func @generic_none(%arg0: tensor<128x128xi32>, %arg1: tensor<128x128xi32>, %arg2: tensor<128x128xi32>) {1016    %0 = linalg.generic {1017      indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d2)>,1018                       affine_map<(d0, d1, d2) -> (d2, d1)>,1019                       affine_map<(d0, d1, d2) -> (d0, d1)>],1020      iterator_types = ["parallel", "parallel", "reduction"]}1021      ins(%arg0, %arg1 : tensor<128x128xi32>, tensor<128x128xi32>)1022      outs(%arg2 : tensor<128x128xi32>) {1023      ^bb0(%in: i32, %in_0: i32, %out: i32):1024        linalg.yield %out : i321025      } -> tensor<128x128xi32>1026    return1027  }1028}1029 1030// -----1031 1032module attributes { transform.with_named_sequence } {1033  transform.named_sequence @match_convolution(%arg0: !transform.any_op {transform.readonly})1034    -> (!transform.any_op, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>) {1035    %1:8 = transform.match.structured %arg0 : (!transform.any_op) -> (!transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>) {1036    ^bb0(%struct: !transform.any_op):1037      transform.match.structured.body %struct { contraction = ["arith.mulf", "arith.addf"] } : !transform.any_op1038      %0:8 = transform.match.structured.classify_convolution_dims %struct1039        : (!transform.any_op) -> (!transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>)1040      transform.match.structured.yield %0#0, %0#1, %0#2, %0#3, %0#4, %0#5, %0#6, %0#71041        : !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>1042    }1043    transform.yield %arg0, %1#0, %1#1, %1#2, %1#3, %1#4, %1#5, %1#6, %1#7 : !transform.any_op, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>, !transform.param<i64>1044  }1045 1046  transform.named_sequence @print_convolution(1047      %op: !transform.any_op {transform.readonly},1048      %batch: !transform.param<i64> {transform.readonly},1049      %oi: !transform.param<i64> {transform.readonly},1050      %oc: !transform.param<i64> {transform.readonly},1051      %fl: !transform.param<i64> {transform.readonly},1052      %ic: !transform.param<i64> {transform.readonly},1053      %depth: !transform.param<i64> {transform.readonly},1054      %strides: !transform.param<i64> {transform.readonly},1055      %dilations: !transform.param<i64> {transform.readonly}) {1056    transform.debug.emit_remark_at %op, "convolution" : !transform.any_op1057    transform.debug.emit_param_as_remark %batch, "batch dims" at %op : !transform.param<i64>, !transform.any_op1058    transform.debug.emit_param_as_remark %oi, "output image dims" at %op : !transform.param<i64>, !transform.any_op1059    transform.debug.emit_param_as_remark %oc, "output channel dims" at %op : !transform.param<i64>, !transform.any_op1060    transform.debug.emit_param_as_remark %fl, "filter loop dims" at %op : !transform.param<i64>, !transform.any_op1061    transform.debug.emit_param_as_remark %ic, "input channel dims" at %op : !transform.param<i64>, !transform.any_op1062    transform.debug.emit_param_as_remark %depth, "depth dims" at %op : !transform.param<i64>, !transform.any_op1063    transform.debug.emit_param_as_remark %strides, "strides" at %op : !transform.param<i64>, !transform.any_op1064    transform.debug.emit_param_as_remark %dilations, "dilations" at %op : !transform.param<i64>, !transform.any_op1065    transform.yield1066  }1067 1068  transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.consumed}) {1069    %3 = transform.foreach_match in %arg0 @match_convolution -> @print_convolution : (!transform.any_op) -> !transform.any_op1070    transform.yield1071  }1072}1073 1074module attributes { transform.target_tag = "start_here" } {1075  func.func @convolution_simple(%input: tensor<10x20x30xf32>, %filter: tensor<3x30x15xf32>) -> tensor<10x18x15xf64> {1076    %cst = arith.constant 0.0 : f641077    %empty = tensor.empty() : tensor<10x18x15xf64>1078    %fill = linalg.fill ins(%cst : f64) outs(%empty : tensor<10x18x15xf64>) -> tensor<10x18x15xf64>1079    // expected-remark @below {{convolution}}1080    // expected-remark @below {{batch dims 0}}1081    // expected-remark @below {{output image dims 1}}1082    // expected-remark @below {{output channel dims 2}}1083    // expected-remark @below {{filter loop dims 3}}1084    // expected-remark @below {{input channel dims 4}}1085    // expected-remark @below {{depth dims}}1086    // expected-remark @below {{strides 1}}1087    // expected-remark @below {{dilations 1}}1088    %result = linalg.conv_1d_nwc_wcf {dilations = dense<1> : tensor<1xi64>,1089                                      strides = dense<1> : tensor<1xi64>}1090       ins(%input, %filter: tensor<10x20x30xf32>, tensor<3x30x15xf32>) outs(%fill: tensor<10x18x15xf64>) -> tensor<10x18x15xf64>1091    return %result : tensor<10x18x15xf64>1092  }1093 1094  func.func @convolution_depthwise(%input: tensor<1x10x196x48xf32>, %filter: tensor<1x4x48xf32>) -> tensor<1x10x191x48xf32> {1095    %cst = arith.constant 0.0 : f32 1096    %empty = tensor.empty() : tensor<1x10x191x48xf32>1097    %fill = linalg.fill ins(%cst : f32) outs(%empty : tensor<1x10x191x48xf32>) -> tensor<1x10x191x48xf32>1098    // expected-remark @below {{convolution}}1099    // expected-remark @below {{batch dims 0}}1100    // expected-remark @below {{output image dims 1 : i64, 2 : i64}}1101    // expected-remark @below {{output channel dims}}1102    // expected-remark @below {{filter loop dims 4 : i64, 5 : i64}}1103    // expected-remark @below {{input channel dims}}1104    // expected-remark @below {{depth dims 3}}1105    // expected-remark @below {{strides 1 : i64, 1 : i64}}1106    // expected-remark @below {{dilations 1 : i64, 1 : i64}}1107    %result = linalg.depthwise_conv_2d_nhwc_hwc {1108      dilations = dense<1> : tensor<2xi64>,1109      strides = dense<1> : tensor<2xi64>}1110      ins(%input, %filter : tensor<1x10x196x48xf32>, tensor<1x4x48xf32>)1111      outs(%fill : tensor<1x10x191x48xf32>) -> tensor<1x10x191x48xf32>1112 1113    return %result : tensor<1x10x191x48xf32>1114  }1115 1116  func.func @convolution_multi_channel(%input: tensor<2x34x68x16xf32>, %filter: tensor<8x2x3x5x16x16xf32>) -> tensor<8x32x32x16xf32> {1117    %cst = arith.constant 0.0 : f321118    %empty = tensor.empty() : tensor<8x32x32x16xf32>1119    %fill = linalg.fill ins(%cst : f32) outs(%empty : tensor<8x32x32x16xf32>) -> tensor<8x32x32x16xf32>1120    // expected-remark @below {{convolution}}1121    // expected-remark @below {{batch dims}}1122    // expected-remark @below {{output image dims 1 : i64, 2 : i64}}1123    // expected-remark @below {{output channel dims 0 : i64, 3 : i64}}1124    // expected-remark @below {{filter loop dims 5 : i64, 6 : i64}}1125    // expected-remark @below {{input channel dims 4 : i64, 7 : i64}}1126    // expected-remark @below {{depth dims}}1127    // expected-remark @below {{strides 1 : i64, 2 : i64}}1128    // expected-remark @below {{dilations 1 : i64, 1 : i64}}1129    %result = linalg.generic {1130        indexing_maps = [1131            affine_map<(d0, d1, d2, d3, d4, d5, d6, d7) -> (d4, d1 + d5, 2 * d2 + d6, d7)>,1132            affine_map<(d0, d1, d2, d3, d4, d5, d6, d7) -> (d0, d4, d5, d6, d7, d3)>,1133            affine_map<(d0, d1, d2, d3, d4, d5, d6, d7) -> (d0, d1, d2, d3)>],1134        iterator_types = ["parallel", "parallel", "parallel", "parallel", "reduction", "reduction", "reduction", "reduction"]}1135        ins(%input, %filter : tensor<2x34x68x16xf32>, tensor<8x2x3x5x16x16xf32>) outs(%fill : tensor<8x32x32x16xf32>) {1136          ^bb0(%in: f32, %in_0: f32, %out: f32):1137            %mul = arith.mulf %in, %in_0 : f321138            %add = arith.addf %mul, %out : f321139            linalg.yield %add : f321140          } -> tensor<8x32x32x16xf32>1141    return %result : tensor<8x32x32x16xf32>1142  }1143}1144