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