403 lines · plain
1// RUN: mlir-opt -transform-interpreter -split-input-file -canonicalize -cse %s | FileCheck %s2 3func.func @gemm(%arg0 : memref<?x?xf32>, %arg1 : memref<?x?xf32>,4 %arg2 : memref<?x?xf32>) {5 linalg.matmul ins(%arg0, %arg1 : memref<?x?xf32>, memref<?x?xf32>)6 outs(%arg2 : memref<?x?xf32>)7 return8}9 10module attributes {transform.with_named_sequence} {11 transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {12 %matmul = transform.structured.match ops{["linalg.matmul"]} in %arg113 : (!transform.any_op) -> !transform.any_op14 %0 = transform.structured.convert_to_loops %matmul15 : (!transform.any_op) -> (!transform.any_op)16 transform.yield17 }18}19// CHECK-LABEL: func @gemm20// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]]: memref<?x?xf32>21// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]]: memref<?x?xf32>22// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]+]]: memref<?x?xf32>23// CHECK-DAG: %[[C0:.+]] = arith.constant 0 : index24// CHECK-DAG: %[[M:.+]] = memref.dim %[[ARG0]], %[[C0]]25// CHECK-DAG: %[[C1:.+]] = arith.constant 1 : index26// CHECK-DAG: %[[K:.+]] = memref.dim %[[ARG0]], %[[C1]]27// CHECK-DAG: %[[N:.+]] = memref.dim %[[ARG1]], %[[C1]]28// CHECK: scf.for %[[IV0:[a-zA-Z0-9]+]] = %[[C0]] to %[[M]] step %[[C1]]29// CHECK: scf.for %[[IV1:[a-zA-Z0-9]+]] = %[[C0]] to %[[N]] step %[[C1]]30// CHECK: scf.for %[[IV2:[a-zA-Z0-9]+]] = %[[C0]] to %[[K]] step %[[C1]]31// CHECK-DAG: %[[LHS:.+]] = memref.load %[[ARG0]][%[[IV0]], %[[IV2]]]32// CHECK-DAG: %[[RHS:.+]] = memref.load %[[ARG1]][%[[IV2]], %[[IV1]]]33// CHECK-DAG: %[[OUT:.+]] = memref.load %[[ARG2]][%[[IV0]], %[[IV1]]]34// CHECK: %[[MULF:.+]] = arith.mulf %[[LHS]], %[[RHS]]35// CHECK: %[[ADDF:.+]] = arith.addf %[[OUT]], %[[MULF]]36// CHECK: memref.store %[[ADDF]], %[[ARG2]][%[[IV0]], %[[IV1]]]37// CHECK-NOT: linalg.matmul ins(%arg0, %arg1 : memref<?x?xf32>, memref<?x?xf32>)38 39// -----40 41func.func @gemm(%arg0 : memref<?x?xf32>, %arg1 : memref<?x?xf32>,42 %arg2 : memref<?x?xf32>, %arg3 : memref<?xf32>, %arg4 : memref<?xf32>) {43 linalg.matmul ins(%arg0, %arg1 : memref<?x?xf32>, memref<?x?xf32>)44 outs(%arg2 : memref<?x?xf32>)45 linalg.matvec ins(%arg0, %arg3 : memref<?x?xf32>, memref<?xf32>)46 outs(%arg4 : memref<?xf32>)47 return48}49 50module attributes {transform.with_named_sequence} {51 transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {52 %linalg_ops = transform.structured.match interface{TilingInterface} in %arg153 : (!transform.any_op) -> !transform.any_op54 %0 = transform.structured.convert_to_loops %linalg_ops55 : (!transform.any_op) -> (!transform.any_op)56 %1:5 = transform.split_handle %057 : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op, !transform.any_op, !transform.any_op)58 transform.yield59 }60}61// CHECK-LABEL: func @gemm62// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]]: memref<?x?xf32>63// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]]: memref<?x?xf32>64// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]+]]: memref<?x?xf32>65// CHECK-SAME: %[[ARG3:[a-zA-Z0-9]+]]: memref<?xf32>66// CHECK-SAME: %[[ARG4:[a-zA-Z0-9]+]]: memref<?xf32>67// CHECK-DAG: %[[C0:.+]] = arith.constant 0 : index68// CHECK-DAG: %[[M:.+]] = memref.dim %[[ARG0]], %[[C0]]69// CHECK-DAG: %[[C1:.+]] = arith.constant 1 : index70// CHECK-DAG: %[[K:.+]] = memref.dim %[[ARG0]], %[[C1]]71// CHECK-DAG: %[[N:.+]] = memref.dim %[[ARG1]], %[[C1]]72// CHECK: scf.for %[[IV0:[a-zA-Z0-9]+]] = %[[C0]] to %[[M]] step %[[C1]]73// CHECK: scf.for %[[IV1:[a-zA-Z0-9]+]] = %[[C0]] to %[[N]] step %[[C1]]74// CHECK: scf.for %[[IV2:[a-zA-Z0-9]+]] = %[[C0]] to %[[K]] step %[[C1]]75// CHECK-DAG: %[[LHS:.+]] = memref.load %[[ARG0]][%[[IV0]], %[[IV2]]]76// CHECK-DAG: %[[RHS:.+]] = memref.load %[[ARG1]][%[[IV2]], %[[IV1]]]77// CHECK-DAG: %[[OUT:.+]] = memref.load %[[ARG2]][%[[IV0]], %[[IV1]]]78// CHECK: %[[MULF:.+]] = arith.mulf %[[LHS]], %[[RHS]]79// CHECK: %[[ADDF:.+]] = arith.addf %[[OUT]], %[[MULF]]80// CHECK: memref.store %[[ADDF]], %[[ARG2]][%[[IV0]], %[[IV1]]]81// CHECK: scf.for %[[IV3:[a-zA-Z0-9]+]] = %[[C0]] to %[[M]] step %[[C1]]82// CHECK: scf.for %[[IV4:[a-zA-Z0-9]+]] = %[[C0]] to %[[K]] step %[[C1]]83// CHECK-DAG: %[[LHS:.+]] = memref.load %[[ARG0]][%[[IV3]], %[[IV4]]]84// CHECK-DAG: %[[RHS:.+]] = memref.load %[[ARG3]][%[[IV4]]]85// CHECK-DAG: %[[OUT:.+]] = memref.load %[[ARG4]][%[[IV3]]]86// CHECK: %[[MULF:.+]] = arith.mulf %[[LHS]], %[[RHS]]87// CHECK: %[[ADDF:.+]] = arith.addf %[[OUT]], %[[MULF]]88// CHECK: memref.store %[[ADDF]], %[[ARG4]][%[[IV3]]]89 90// -----91 92func.func @indexed_generic(%arg0 : memref<200x300xi32>, %arg1 : memref<300xi16>,93 %arg2 : memref<200xi8>, %arg3 : memref<300x200xi64>) {94 linalg.generic {95 indexing_maps = [affine_map<(d0, d1) -> (d0, d1)>, affine_map<(d0, d1) -> (d1)>,96 affine_map<(d0, d1) -> (d0)>, affine_map<(d0, d1) -> (d1, d0)>],97 iterator_types = ["parallel", "parallel"]}98 ins(%arg0, %arg1, %arg2 : memref<200x300xi32>, memref<300xi16>, memref<200xi8>)99 outs(%arg3 : memref<300x200xi64>) {100 ^bb0(%b0 : i32, %b1 : i16, %b2 : i8, %b3 : i64):101 %0 = linalg.index 0 : index102 %1 = arith.index_cast %0 : index to i16103 %2 = arith.muli %b1, %1 : i16104 %3 = linalg.index 1 : index105 %4 = arith.index_cast %3 : index to i8106 %5 = arith.muli %b2, %4 : i8107 %6 = arith.extsi %2 : i16 to i32108 %7 = arith.extsi %5 : i8 to i32109 %8 = arith.addi %6, %7 : i32110 %9 = arith.addi %8, %b0 : i32111 %10 = arith.extsi %9 : i32 to i64112 linalg.yield %10 : i64113 }114 return115}116 117module attributes {transform.with_named_sequence} {118 transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {119 %generic = transform.structured.match ops{["linalg.generic"]} in %arg1120 : (!transform.any_op) -> !transform.any_op121 %0 = transform.structured.convert_to_loops %generic122 : (!transform.any_op) -> (!transform.any_op)123 transform.yield124 }125}126// CHECK-LABEL: func @indexed_generic127// CHECK-SAME: %[[ARG0:.+]]: memref<200x300xi32>128// CHECK-SAME: %[[ARG1:.+]]: memref<300xi16>129// CHECK-SAME: %[[ARG2:.+]]: memref<200xi8>130// CHECK-SAME: %[[ARG3:.+]]: memref<300x200xi64>131// CHECK-DAG: %[[C0:.+]] = arith.constant 0 : index132// CHECK-DAG: %[[C1:.+]] = arith.constant 1 : index133// CHECK-DAG: %[[C200:.+]] = arith.constant 200 : index134// CHECK-DAG: %[[C300:.+]] = arith.constant 300 : index135// CHECK: scf.for %[[IV0:[a-zA-Z0-9]+]] = %[[C0]] to %[[C200]] step %[[C1]]136// CHECK: scf.for %[[IV1:[a-zA-Z0-9]+]] = %[[C0]] to %[[C300]] step %[[C1]]137// CHECK-DAG: %[[B0:.+]] = memref.load %[[ARG0]][%[[IV0]], %[[IV1]]]138// CHECK-DAG: %[[B1:.+]] = memref.load %[[ARG1]][%[[IV1]]]139// CHECK-DAG: %[[B2:.+]] = memref.load %[[ARG2]][%[[IV0]]]140// CHECK: %[[T1:.+]] = arith.index_cast %[[IV0]]141// CHECK: %[[T2:.+]] = arith.muli %[[B1]], %[[T1]]142// CHECK: %[[T4:.+]] = arith.index_cast %[[IV1]]143// CHECK: %[[T5:.+]] = arith.muli %[[B2]], %[[T4]]144// CHECK: %[[T6:.+]] = arith.extsi %[[T2]]145// CHECK: %[[T7:.+]] = arith.extsi %[[T5]]146// CHECK: %[[T8:.+]] = arith.addi %[[T6]], %[[T7]]147// CHECK: %[[T9:.+]] = arith.addi %[[T8]], %[[B0]]148// CHECK: %[[T10:.+]] = arith.extsi %[[T9]]149// CHECK: memref.store %[[T10]], %[[ARG3]][%[[IV1]], %[[IV0]]]150 151// -----152 153func.func @conv_strides_and_dilation(%arg0 : memref<?x?x?x?xf32>, %arg1 : memref<?x?x?x?xf32>,154 %arg2 : memref<?x?x?x?xf32>) {155 linalg.conv_2d_nhwc_hwcf {156 strides = dense<[1, 2]> : tensor<2xi64>,157 dilations = dense<[3, 4]> : tensor<2xi64>}158 ins(%arg0, %arg1 : memref<?x?x?x?xf32>, memref<?x?x?x?xf32>)159 outs(%arg2 : memref<?x?x?x?xf32>)160 return161}162 163module attributes {transform.with_named_sequence} {164 transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {165 %conv = transform.structured.match ops{["linalg.conv_2d_nhwc_hwcf"]} in %arg1166 : (!transform.any_op) -> !transform.any_op167 %0 = transform.structured.convert_to_loops %conv168 : (!transform.any_op) -> (!transform.any_op)169 transform.yield170 }171}172 173// CHECK-DAG: #[[MAP0:.+]] = affine_map<(d0, d1) -> (d0 + d1 * 3)>174// CHECK-DAG: #[[MAP1:.+]] = affine_map<(d0, d1) -> (d0 * 2 + d1 * 4)>175// CHECK: func @conv_strides_and_dilation(176// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>177// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>178// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>179// CHECK-DAG: %[[C0:.+]] = arith.constant 0 : index180// CHECK-DAG: %[[C1:.+]] = arith.constant 1 : index181// CHECK-DAG: %[[C2:.+]] = arith.constant 2 : index182// CHECK-DAG: %[[C3:.+]] = arith.constant 3 : index183// CHECK-DAG: %[[N:.+]] = memref.dim %[[ARG0]], %[[C0]]184// CHECK-DAG: %[[C:.+]] = memref.dim %[[ARG0]], %[[C3]]185// CHECK-DAG: %[[H:.+]] = memref.dim %[[ARG1]], %[[C0]]186// CHECK-DAG: %[[W:.+]] = memref.dim %[[ARG1]], %[[C1]]187// CHECK-DAG: %[[F:.+]] = memref.dim %[[ARG1]], %[[C3]]188// CHECK-DAG: %[[P:.+]] = memref.dim %[[ARG2]], %[[C1]]189// CHECK-DAG: %[[Q:.+]] = memref.dim %[[ARG2]], %[[C2]]190// CHECK: scf.for %[[IV0:[a-zA-Z0-9]+]] = %[[C0]] to %[[N]] step %[[C1]]191// CHECK: scf.for %[[IV1:[a-zA-Z0-9]+]] = %[[C0]] to %[[P]] step %[[C1]]192// CHECK: scf.for %[[IV2:[a-zA-Z0-9]+]] = %[[C0]] to %[[Q]] step %[[C1]]193// CHECK: scf.for %[[IV3:[a-zA-Z0-9]+]] = %[[C0]] to %[[F]] step %[[C1]]194// CHECK: scf.for %[[IV4:[a-zA-Z0-9]+]] = %[[C0]] to %[[H]] step %[[C1]]195// CHECK: scf.for %[[IV5:[a-zA-Z0-9]+]] = %[[C0]] to %[[W]] step %[[C1]]196// CHECK: scf.for %[[IV6:[a-zA-Z0-9]+]] = %[[C0]] to %[[C]] step %[[C1]]197// CHECK-DAG: %[[I:.+]] = affine.apply #[[MAP0]](%[[IV1]], %[[IV4]])198// CHECK-DAG: %[[J:.+]] = affine.apply #[[MAP1]](%[[IV2]], %[[IV5]])199// CHECK-DAG: %[[T9:.+]] = memref.load %[[ARG0]][%[[IV0]], %[[I]], %[[J]], %[[IV6]]]200// CHECK-DAG: %[[T10:.+]] = memref.load %[[ARG1]][%[[IV4]], %[[IV5]], %[[IV6]], %[[IV3]]]201// CHECK-DAG: %[[T11:.+]] = memref.load %[[ARG2]][%[[IV0]], %[[IV1]], %[[IV2]], %[[IV3]]]202// CHECK: %[[T12:.+]] = arith.mulf %[[T9]], %[[T10]]203// CHECK: %[[T13:.+]] = arith.addf %[[T11]], %[[T12]]204// CHECK: memref.store %[[T13]], %[[ARG2]][%[[IV0]], %[[IV1]], %[[IV2]], %[[IV3]]]205 206// -----207 208func.func @pool_strides_and_dilation(%arg0 : memref<?x?x?x?xf32>, %arg1 : memref<?x?xf32>,209 %arg2 : memref<?x?x?x?xf32>) {210 linalg.pooling_nhwc_max {211 strides = dense<[1, 2]> : tensor<2xi64>,212 dilations = dense<[3, 4]> : tensor<2xi64>}213 ins(%arg0, %arg1 : memref<?x?x?x?xf32>, memref<?x?xf32>)214 outs(%arg2 : memref<?x?x?x?xf32>)215 return216}217 218module attributes {transform.with_named_sequence} {219 transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {220 %pool = transform.structured.match ops{["linalg.pooling_nhwc_max"]} in %arg1221 : (!transform.any_op) -> !transform.any_op222 %0 = transform.structured.convert_to_loops %pool223 : (!transform.any_op) -> (!transform.any_op)224 transform.yield225 }226}227 228// CHECK-DAG: #[[MAP0:.+]] = affine_map<(d0, d1) -> (d0 + d1 * 3)>229// CHECK-DAG: #[[MAP1:.+]] = affine_map<(d0, d1) -> (d0 * 2 + d1 * 4)>230// CHECK: func @pool_strides_and_dilation231// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>232// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]]: memref<?x?xf32>233// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>234// CHECK-DAG: %[[C0:.+]] = arith.constant 0 : index235// CHECK-DAG: %[[C1:.+]] = arith.constant 1 : index236// CHECK-DAG: %[[C2:.+]] = arith.constant 2 : index237// CHECK-DAG: %[[C3:.+]] = arith.constant 3 : index238// CHECK-DAG: %[[N:.+]] = memref.dim %[[ARG0]], %[[C0]]239// CHECK-DAG: %[[C:.+]] = memref.dim %[[ARG0]], %[[C3]]240// CHECK-DAG: %[[H:.+]] = memref.dim %[[ARG1]], %[[C0]]241// CHECK-DAG: %[[W:.+]] = memref.dim %[[ARG1]], %[[C1]]242// CHECK-DAG: %[[P:.+]] = memref.dim %[[ARG2]], %[[C1]]243// CHECK-DAG: %[[Q:.+]] = memref.dim %[[ARG2]], %[[C2]]244// CHECK: scf.for %[[IV0:[a-zA-Z0-9]+]] = %[[C0]] to %[[N]] step %[[C1]]245// CHECK: scf.for %[[IV1:[a-zA-Z0-9]+]] = %[[C0]] to %[[P]] step %[[C1]]246// CHECK: scf.for %[[IV2:[a-zA-Z0-9]+]] = %[[C0]] to %[[Q]] step %[[C1]]247// CHECK: scf.for %[[IV3:[a-zA-Z0-9]+]] = %[[C0]] to %[[C]] step %[[C1]]248// CHECK: scf.for %[[IV4:[a-zA-Z0-9]+]] = %[[C0]] to %[[H]] step %[[C1]]249// CHECK: scf.for %[[IV5:[a-zA-Z0-9]+]] = %[[C0]] to %[[W]] step %[[C1]]250// CHECK-DAG: %[[I:.+]] = affine.apply #[[MAP0]](%[[IV1]], %[[IV4]])251// CHECK-DAG: %[[J:.+]] = affine.apply #[[MAP1]](%[[IV2]], %[[IV5]])252// CHECK-DAG: %[[T8:.+]] = memref.load %[[ARG0]][%[[IV0]], %[[I]], %[[J]], %[[IV3]]]253// CHECK-DAG: %[[T9:.+]] = memref.load %[[ARG2]][%[[IV0]], %[[IV1]], %[[IV2]], %[[IV3]]]254// CHECK: %[[T10:.+]] = arith.maximumf %[[T9]], %[[T8]]255// CHECK: memref.store %[[T10]], %[[ARG2]][%[[IV0]], %[[IV1]], %[[IV2]], %[[IV3]]]256 257// -----258 259func.func @map(%lhs: memref<64xf32>,260 %rhs: memref<64xf32>, %init: memref<64xf32>) {261 linalg.map ins(%lhs, %rhs : memref<64xf32>, memref<64xf32>)262 outs(%init : memref<64xf32>)263 (%in: f32, %in_0: f32, %out: f32) {264 %0 = arith.addf %in, %in_0 : f32265 linalg.yield %0 : f32266 }267 return268}269 270module attributes {transform.with_named_sequence} {271 transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {272 %map = transform.structured.match ops{["linalg.map"]} in %arg1273 : (!transform.any_op) -> !transform.any_op274 %0 = transform.structured.convert_to_loops %map275 : (!transform.any_op) -> (!transform.any_op)276 transform.yield277 }278}279// CHECK-LABEL: func.func @map(280// CHECK-SAME: %[[LHS:[a-zA-Z0-9]+]]: memref<64xf32>,281// CHECK-SAME: %[[RHS:[a-zA-Z0-9]+]]: memref<64xf32>,282// CHECK-SAME: %[[OUT:[a-zA-Z0-9]+]]: memref<64xf32>) {283 284// CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index285// CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index286// CHECK-DAG: %[[C64:.*]] = arith.constant 64 : index287 288// CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[C64]] step %[[C1]] {289// CHECK: %[[LHS_ELEM:.*]] = memref.load %[[LHS]][%[[I]]]290// CHECK: %[[RHS_ELEM:.*]] = memref.load %[[RHS]][%[[I]]]291// CHECK: %[[ADD:.*]] = arith.addf %[[LHS_ELEM]], %[[RHS_ELEM]]292// CHECK: memref.store %[[ADD]], %[[OUT]][%[[I]]]293 294// -----295 296func.func @transpose(%arg0: memref<16x32x64xf32>,297 %arg1: memref<32x64x16xf32>) {298 linalg.transpose ins(%arg0 : memref<16x32x64xf32>)299 outs(%arg1 : memref<32x64x16xf32>) permutation = [1, 2, 0]300 return301}302 303module attributes {transform.with_named_sequence} {304 transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {305 %transpose = transform.structured.match ops{["linalg.transpose"]} in %arg1306 : (!transform.any_op) -> !transform.any_op307 %0 = transform.structured.convert_to_loops %transpose308 : (!transform.any_op) -> (!transform.any_op)309 transform.yield310 }311}312// CHECK-LABEL: func.func @transpose(313// CHECK-SAME: %[[IN:[a-zA-Z0-9]+]]: memref<16x32x64xf32>,314// CHECK-SAME: %[[OUT:[a-zA-Z0-9]+]]: memref<32x64x16xf32>)315 316// CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index317// CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index318// CHECK-DAG: %[[C16:.*]] = arith.constant 16 : index319// CHECK-DAG: %[[C32:.*]] = arith.constant 32 : index320// CHECK-DAG: %[[C64:.*]] = arith.constant 64 : index321 322// CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[C32]] step %[[C1]] {323// CHECK: scf.for %[[J:.*]] = %[[C0]] to %[[C64]] step %[[C1]] {324// CHECK: scf.for %[[K:.*]] = %[[C0]] to %[[C16]] step %[[C1]] {325// CHECK: %[[ELEM:.*]] = memref.load %[[IN]][%[[K]], %[[I]], %[[J]]]326// CHECK: memref.store %[[ELEM]], %[[OUT]][%[[I]], %[[J]], %[[K]]]327 328// -----329 330func.func @reduce(%arg0: memref<16x32x64xf32>,331 %arg1: memref<16x64xf32>) {332 linalg.reduce ins(%arg0 : memref<16x32x64xf32>)333 outs(%arg1 : memref<16x64xf32>) dimensions = [1]334 (%in: f32, %init: f32) {335 %0 = arith.addf %in, %init : f32336 linalg.yield %0 : f32337 }338 return339}340 341module attributes {transform.with_named_sequence} {342 transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {343 %reduce = transform.structured.match ops{["linalg.reduce"]} in %arg1344 : (!transform.any_op) -> !transform.any_op345 %0 = transform.structured.convert_to_loops %reduce346 : (!transform.any_op) -> (!transform.any_op)347 transform.yield348 }349}350// CHECK-LABEL: func.func @reduce(351// CHECK-SAME: %[[IN:[a-zA-Z0-9]+]]: memref<16x32x64xf32>,352// CHECK-SAME: %[[OUT:[a-zA-Z0-9]+]]: memref<16x64xf32>353 354// CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index355// CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index356// CHECK-DAG: %[[C16:.*]] = arith.constant 16 : index357// CHECK-DAG: %[[C32:.*]] = arith.constant 32 : index358// CHECK-DAG: %[[C64:.*]] = arith.constant 64 : index359 360// CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[C16]] step %[[C1]] {361// CHECK: scf.for %[[J:.*]] = %[[C0]] to %[[C32]] step %[[C1]] {362// CHECK: scf.for %[[K:.*]] = %[[C0]] to %[[C64]] step %[[C1]] {363// CHECK: %[[IN_ELEM:.*]] = memref.load %[[IN]][%[[I]], %[[J]], %[[K]]]364// CHECK: %[[OUT_ELEM:.*]] = memref.load %[[OUT]][%[[I]], %[[K]]]365// CHECK: %[[ADD:.*]] = arith.addf %[[IN_ELEM]], %[[OUT_ELEM]]366// CHECK: memref.store %[[ADD]], %[[OUT]][%[[I]], %[[K]]]367 368// -----369 370func.func @broadcast(%input: memref<8x32xf32>,371 %init: memref<8x16x32xf32>) {372 linalg.broadcast373 ins(%input:memref<8x32xf32>)374 outs(%init:memref<8x16x32xf32>)375 dimensions = [1]376 func.return377}378 379module attributes {transform.with_named_sequence} {380 transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {381 %broadcast = transform.structured.match ops{["linalg.broadcast"]} in %arg1382 : (!transform.any_op) -> !transform.any_op383 %0 = transform.structured.convert_to_loops %broadcast384 : (!transform.any_op) -> (!transform.any_op)385 transform.yield386 }387}388// CHECK-LABEL: func.func @broadcast(389// CHECK-SAME: %[[IN:[a-zA-Z0-9]+]]: memref<8x32xf32>,390// CHECK-SAME: %[[OUT:[a-zA-Z0-9]+]]: memref<8x16x32xf32>391 392// CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index393// CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index394// CHECK-DAG: %[[C8:.*]] = arith.constant 8 : index395// CHECK-DAG: %[[C16:.*]] = arith.constant 16 : index396// CHECK-DAG: %[[C32:.*]] = arith.constant 32 : index397 398// CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[C8]] step %[[C1]] {399// CHECK: scf.for %[[J:.*]] = %[[C0]] to %[[C16]] step %[[C1]] {400// CHECK: scf.for %[[K:.*]] = %[[C0]] to %[[C32]] step %[[C1]] {401// CHECK: %[[ELEM:.*]] = memref.load %[[IN]][%[[I]], %[[K]]]402// CHECK: memref.store %[[ELEM]], %[[OUT]][%[[I]], %[[J]], %[[K]]]403