515 lines · plain
1// RUN: mlir-opt --transform-interpreter --split-input-file -canonicalize -cse --verify-diagnostics %s2 3func.func @map_nested_forall_to_threads_not_gpu_launch() -> () {4 %1 = tensor.empty() : tensor<4xf32>5 return6}7module attributes {transform.with_named_sequence} {8 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {9 %funcop = transform.structured.match ops{["tensor.empty"]} in %arg0 : (!transform.any_op) -> !transform.any_op10 // expected-error @below {{Given target is not a gpu.launch}}11 %1 = transform.gpu.map_nested_forall_to_threads %funcop block_dims = [1, 1, 1] : (!transform.any_op) -> !transform.any_op12 transform.yield13 }14}15 16// -----17 18func.func @map_nested_forall_to_threads_excessive_threads(%x: memref<2 x 32 x f32>, %y: memref<2 x 32 x f32>, %t: memref<32 x f32>, %alpha : f32, %stream : !gpu.async.token) -> memref<2 x 32 x f32> {19 %one = arith.constant 1 : index20 %c900 = arith.constant 900 : index21 %c9 = arith.constant 9 : index22 %c7 = arith.constant 7 : index23 %name = gpu.launch async[%stream] blocks(%arg3, %arg4, %arg5) in (%arg9 = %one, %arg10 = %one, %arg11 = %one)24 threads(%arg6, %arg7, %arg8) in (%arg12 = %one, %arg13 = %one, %arg14 = %one)25 {26 scf.forall (%i, %j) in (%c7, %c900) {27 %4 = memref.load %x[%i, %j] : memref<2 x 32 x f32>28 %5 = memref.load %y[%i, %j] : memref<2 x 32 x f32>29 %6 = math.fma %alpha, %4, %5 : f3230 memref.store %6, %y[%i, %j] : memref<2 x 32 x f32>31 } { mapping = [#gpu.thread<y>, #gpu.thread<x>] }32 gpu.terminator33 }34 35 %name2 = gpu.launch async[%stream] blocks(%arg3, %arg4, %arg5) in (%arg9 = %one, %arg10 = %one, %arg11 = %one)36 threads(%arg6, %arg7, %arg8) in (%arg12 = %one, %arg13 = %one, %arg14 = %one)37 {38 scf.forall (%i, %j) in (%c7, %c9) {39 %4 = memref.load %x[%i, %j] : memref<2 x 32 x f32>40 %5 = memref.load %y[%i, %j] : memref<2 x 32 x f32>41 %6 = math.fma %alpha, %4, %5 : f3242 memref.store %6, %y[%i, %j] : memref<2 x 32 x f32>43 } { mapping = [#gpu.thread<y>, #gpu.thread<x>] }44 gpu.terminator45 }46 47 return %y : memref<2 x 32 x f32>48}49 50module attributes {transform.with_named_sequence} {51 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {52 %funcop = transform.structured.match ops{["gpu.launch"]} in %arg0 : (!transform.any_op) -> !transform.any_op53 // expected-error @below {{Trying to launch a GPU kernel with grid_dims = (1, 1, 1) block_dims = (1200, 9, 1). It is larger than the limits.}}54 // expected-note @below {{"block_dims" is too large}}55 transform.gpu.map_nested_forall_to_threads %funcop block_dims = [1200, 9, 1] : (!transform.any_op) -> !transform.any_op56 transform.yield57 }58}59 60// -----61 62func.func @map_nested_forall_to_threads_fewer_threads(%x: memref<2 x 32 x f32>, %y: memref<2 x 32 x f32>, %t: memref<32 x f32>, %alpha : f32, %stream : !gpu.async.token) -> memref<2 x 32 x f32> {63 %one = arith.constant 1 : index64 %c900 = arith.constant 900 : index65 %c9 = arith.constant 9 : index66 %c7 = arith.constant 7 : index67 %name = gpu.launch async[%stream] blocks(%arg3, %arg4, %arg5) in (%arg9 = %one, %arg10 = %one, %arg11 = %one)68 threads(%arg6, %arg7, %arg8) in (%arg12 = %one, %arg13 = %one, %arg14 = %one)69 {70 scf.forall (%i, %j) in (%c7, %c900) {71 %4 = memref.load %x[%i, %j] : memref<2 x 32 x f32>72 %5 = memref.load %y[%i, %j] : memref<2 x 32 x f32>73 %6 = math.fma %alpha, %4, %5 : f3274 memref.store %6, %y[%i, %j] : memref<2 x 32 x f32>75 } { mapping = [#gpu.thread<y>, #gpu.thread<x>] }76 gpu.terminator77 }78 79 %name2 = gpu.launch async[%stream] blocks(%arg3, %arg4, %arg5) in (%arg9 = %one, %arg10 = %one, %arg11 = %one)80 threads(%arg6, %arg7, %arg8) in (%arg12 = %one, %arg13 = %one, %arg14 = %one)81 {82 scf.forall (%i, %j) in (%c7, %c9) {83 %4 = memref.load %x[%i, %j] : memref<2 x 32 x f32>84 %5 = memref.load %y[%i, %j] : memref<2 x 32 x f32>85 %6 = math.fma %alpha, %4, %5 : f3286 memref.store %6, %y[%i, %j] : memref<2 x 32 x f32>87 } { mapping = [#gpu.thread<y>, #gpu.thread<x>] }88 gpu.terminator89 }90 91 return %y : memref<2 x 32 x f32>92}93 94module attributes {transform.with_named_sequence} {95 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {96 %funcop = transform.structured.match ops{["gpu.launch"]} in %arg0 : (!transform.any_op) -> !transform.any_op97 // expected-error @below {{the number of required parallel resources (blocks or threads) 6300 overflows the number of available resources 512}}98 transform.gpu.map_nested_forall_to_threads %funcop block_dims = [128, 4, 1] : (!transform.any_op) -> !transform.any_op99 transform.yield100 }101}102 103// -----104 105func.func @map_nested_forall_to_threads_dynamic_trip_count(%x: memref<2 x 32 x f32>, %y: memref<2 x 32 x f32>, %t: memref<32 x f32>, %alpha : f32, %stream : !gpu.async.token, %c9 : index, %c7 : index) -> memref<2 x 32 x f32> {106 %one = arith.constant 1 : index107 %c900 = arith.constant 900 : index108 %name = gpu.launch async[%stream] blocks(%arg3, %arg4, %arg5) in (%arg9 = %one, %arg10 = %one, %arg11 = %one)109 threads(%arg6, %arg7, %arg8) in (%arg12 = %one, %arg13 = %one, %arg14 = %one)110 {111 scf.forall (%i, %j) in (%c7, %c900) {112 %4 = memref.load %x[%i, %j] : memref<2 x 32 x f32>113 %5 = memref.load %y[%i, %j] : memref<2 x 32 x f32>114 %6 = math.fma %alpha, %4, %5 : f32115 memref.store %6, %y[%i, %j] : memref<2 x 32 x f32>116 } { mapping = [#gpu.thread<y>, #gpu.thread<x>] }117 gpu.terminator118 }119 return %y : memref<2 x 32 x f32>120}121 122module attributes {transform.with_named_sequence} {123 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {124 %funcop = transform.structured.match ops{["gpu.launch"]} in %arg0 : (!transform.any_op) -> !transform.any_op125 // expected-error @below {{requires statically sized, normalized forall op}}126 transform.gpu.map_nested_forall_to_threads %funcop block_dims = [128, 4, 1] : (!transform.any_op) -> !transform.any_op127 transform.yield128 }129}130 131// -----132 133func.func @map_nested_forall_to_threads_not_buffer(%x: tensor<32x32xf32>, %y: tensor<32x32xf32>, %z: tensor<32x32xf32>, %stream : !gpu.async.token) {134 %one = arith.constant 1 : index135 %name = gpu.launch async[%stream] blocks(%arg3, %arg4, %arg5) in (%arg9 = %one, %arg10 = %one, %arg11 = %one)136 threads(%arg6, %arg7, %arg8) in (%arg12 = %one, %arg13 = %one, %arg14 = %one)137 {138 %t = linalg.matmul ins(%x, %y: tensor<32x32xf32>, tensor<32x32xf32>) outs(%z : tensor<32x32xf32>) -> tensor<32x32xf32>139 gpu.terminator140 }141 return142}143 144module attributes {transform.with_named_sequence} {145 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {146 %matmul = transform.structured.match ops{["linalg.matmul"]} in %arg0 : (!transform.any_op) -> !transform.any_op147 %tiled, %forall = transform.structured.tile_using_forall %matmul num_threads [2, 3, 1] (mapping = [ #gpu.thread<y>, #gpu.thread<x>, #gpu.thread<z> ] )148 : (!transform.any_op) -> (!transform.any_op, !transform.any_op)149 %funcop = transform.structured.match ops{["gpu.launch"]} in %arg0 : (!transform.any_op) -> !transform.any_op150 // expected-error @below {{only bufferized scf.forall can be mapped}}151 transform.gpu.map_nested_forall_to_threads %funcop block_dims = [96, 4, 1] : (!transform.any_op) -> !transform.any_op152 transform.yield153 }154}155 156// -----157 158 159func.func @map_forall_to_blocks_not_gpu_launch() -> () {160 // expected-note @below {{when applied to this payload op}}161 %1 = tensor.empty() : tensor<4xf32>162 return163}164 165module attributes {transform.with_named_sequence} {166 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {167 %funcop = transform.structured.match ops{["tensor.empty"]} in %arg0 : (!transform.any_op) -> !transform.any_op168 // expected-error @below {{Given target is not gpu.launch}}169 %1 = transform.gpu.map_forall_to_blocks %funcop : (!transform.any_op) -> !transform.any_op170 transform.yield171 }172}173 174// -----175 176func.func @map_forall_to_blocks_not_unique(%x: memref<2 x 32 x f32>, %y: memref<2 x 32 x f32>, %t: memref<32 x f32>, %alpha : f32, %stream : !gpu.async.token) -> memref<2 x 32 x f32> {177 %one = arith.constant 1 : index178 %c900 = arith.constant 900 : index179 %c9 = arith.constant 9 : index180 %c7 = arith.constant 7 : index181 // expected-note @below {{when applied to this payload op}}182 %name = gpu.launch async[%stream] blocks(%arg3, %arg4, %arg5) in (%arg9 = %one, %arg10 = %one, %arg11 = %one)183 threads(%arg6, %arg7, %arg8) in (%arg12 = %one, %arg13 = %one, %arg14 = %one)184 {185 scf.forall (%i, %j) in (%c7, %c900) {186 %4 = memref.load %x[%i, %j] : memref<2 x 32 x f32>187 %5 = memref.load %y[%i, %j] : memref<2 x 32 x f32>188 %6 = math.fma %alpha, %4, %5 : f32189 memref.store %6, %y[%i, %j] : memref<2 x 32 x f32>190 } { mapping = [#gpu.thread<y>, #gpu.thread<x>] }191 192 scf.forall (%i, %j) in (%c7, %c9) {193 %4 = memref.load %x[%i, %j] : memref<2 x 32 x f32>194 %5 = memref.load %y[%i, %j] : memref<2 x 32 x f32>195 %6 = math.fma %alpha, %4, %5 : f32196 memref.store %6, %y[%i, %j] : memref<2 x 32 x f32>197 } { mapping = [#gpu.thread<y>, #gpu.thread<x>] }198 gpu.terminator199 }200 201 return %y : memref<2 x 32 x f32>202}203 204module attributes {transform.with_named_sequence} {205 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {206 %funcop = transform.structured.match ops{["gpu.launch"]} in %arg0 : (!transform.any_op) -> !transform.any_op207 // expected-error @below {{could not find a unique topLevel scf.forall}}208 %1 = transform.gpu.map_forall_to_blocks %funcop : (!transform.any_op) -> !transform.any_op209 transform.yield210 }211}212 213// -----214 215// expected-note @below {{when applied to this payload op}}216func.func @map_forall_to_blocks_large_loop(%x: memref<2 x 32 x f32>, %y: memref<2 x 32 x f32>, %t: memref<32 x f32>, %alpha : f32, %stream : !gpu.async.token) -> memref<2 x 32 x f32> {217 %one = arith.constant 1 : index218 %c65537 = arith.constant 65536 : index219 %c9 = arith.constant 9 : index220 %c7 = arith.constant 7 : index221 222 scf.forall (%i, %j) in (%c7, %c65537) {223 %4 = memref.load %x[%i, %j] : memref<2 x 32 x f32>224 %5 = memref.load %y[%i, %j] : memref<2 x 32 x f32>225 %6 = math.fma %alpha, %4, %5 : f32226 memref.store %6, %y[%i, %j] : memref<2 x 32 x f32>227 } { mapping = [#gpu.thread<x>, #gpu.thread<y>] }228 229 scf.forall (%i, %j) in (%c7, %c9) {230 %4 = memref.load %x[%i, %j] : memref<2 x 32 x f32>231 %5 = memref.load %y[%i, %j] : memref<2 x 32 x f32>232 %6 = math.fma %alpha, %4, %5 : f32233 memref.store %6, %y[%i, %j] : memref<2 x 32 x f32>234 } { mapping = [#gpu.thread<y>, #gpu.thread<x>] }235 236 return %y : memref<2 x 32 x f32>237}238 239module attributes {transform.with_named_sequence} {240 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {241 %funcop = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op242 // expected-error @below {{could not find a unique topLevel scf.forall}}243 %1 = transform.gpu.map_forall_to_blocks %funcop { generate_gpu_launch } : (!transform.any_op) -> !transform.any_op244 transform.yield245 }246}247 248// -----249 250func.func @map_forall_to_blocks_large_loop(%x: memref<2 x 32 x f32>, %y: memref<2 x 32 x f32>, %t: memref<32 x f32>, %alpha : f32, %stream : !gpu.async.token) -> memref<2 x 32 x f32> {251 %one = arith.constant 1 : index252 %c65535 = arith.constant 65535 : index253 scf.forall (%i, %j) in (%c65535, %c65535) {254 %4 = memref.load %x[%i, %j] : memref<2 x 32 x f32>255 %5 = memref.load %y[%i, %j] : memref<2 x 32 x f32>256 %6 = math.fma %alpha, %4, %5 : f32257 memref.store %6, %y[%i, %j] : memref<2 x 32 x f32>258 } { mapping = [#gpu.block<x>, #gpu.block<y>] }259 return %y : memref<2 x 32 x f32>260}261 262module attributes {transform.with_named_sequence} {263 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {264 %funcop = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op265 // expected-error @below {{Trying to launch a GPU kernel with grid_dims = (65535, 65535, 1) block_dims = (1, 1, 1). It is larger than the limits.}}266 %1 = transform.gpu.map_forall_to_blocks %funcop generate_gpu_launch : (!transform.any_op) -> !transform.any_op267 transform.yield268 }269}270 271// -----272 273!type = memref<32x32xf32>274func.func @saxpy2d_singleloop(%x: !type, %y: !type, %stream : !gpu.async.token) -> !type {275 %c32 = arith.constant 32 : index276 %one = arith.constant 1 : index277 %name = gpu.launch async[%stream] blocks(%arg3, %arg4, %arg5) in (%arg9 = %one, %arg10 = %one, %arg11 = %one)278 threads(%arg6, %arg7, %arg8) in (%arg12 = %one, %arg13 = %one, %arg14 = %one)279 {280 scf.forall (%i, %j) in (%c32, %c32) {281 %4 = memref.load %x[%i, %j] : !type282 %5 = memref.load %y[%i, %j] : !type283 %6 = arith.mulf %4, %5 : f32284 memref.store %6, %y[%i, %j] : !type285 } { mapping = [#gpu.thread<x>, #gpu.warp<y>] }286 gpu.terminator287 }288 return %y : !type289}290 291module attributes {transform.with_named_sequence} {292 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {293 %funcop = transform.structured.match ops{["gpu.launch"]} in %arg0 : (!transform.any_op) -> !transform.any_op294 // expected-error @below {{cannot mix different mapping types, use nesting}}295 transform.gpu.map_nested_forall_to_threads %funcop block_dims = [32, 32, 1] : (!transform.any_op) -> !transform.any_op296 transform.yield297 }298}299 300// -----301 302!type = memref<32x32xf32>303func.func @saxpy2d_singleloop(%x: !type, %y: !type, %stream : !gpu.async.token) -> !type {304 %c32 = arith.constant 32 : index305 %one = arith.constant 1 : index306 %name = gpu.launch async[%stream] blocks(%arg3, %arg4, %arg5) in (%arg9 = %one, %arg10 = %one, %arg11 = %one)307 threads(%arg6, %arg7, %arg8) in (%arg12 = %one, %arg13 = %one, %arg14 = %one)308 {309 scf.forall (%i, %j) in (%c32, %c32) {310 %4 = memref.load %x[%i, %j] : !type311 %5 = memref.load %y[%i, %j] : !type312 %6 = arith.mulf %4, %5 : f32313 memref.store %6, %y[%i, %j] : !type314 } { mapping = [#gpu.thread<x>, #gpu.thread<x>] }315 gpu.terminator316 }317 return %y : !type318}319 320module attributes {transform.with_named_sequence} {321 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {322 %funcop = transform.structured.match ops{["gpu.launch"]} in %arg0 : (!transform.any_op) -> !transform.any_op323 // expected-error @below {{duplicate attribute, cannot map different loops to the same mapping id}}324 transform.gpu.map_nested_forall_to_threads %funcop block_dims = [32, 32, 1] : (!transform.any_op) -> !transform.any_op325 transform.yield326 }327}328 329// -----330 331!type = memref<32x32xf32>332func.func @saxpy2d_singleloop(%x: !type, %y: !type, %stream : !gpu.async.token) -> !type {333 %c32 = arith.constant 32 : index334 %one = arith.constant 1 : index335 %name = gpu.launch async[%stream] blocks(%arg3, %arg4, %arg5) in (%arg9 = %one, %arg10 = %one, %arg11 = %one)336 threads(%arg6, %arg7, %arg8) in (%arg12 = %one, %arg13 = %one, %arg14 = %one)337 {338 scf.forall (%i, %j) in (%c32, %c32) {339 %4 = memref.load %x[%i, %j] : !type340 %5 = memref.load %y[%i, %j] : !type341 %6 = arith.mulf %4, %5 : f32342 memref.store %6, %y[%i, %j] : !type343 } { mapping = [#gpu.thread<x>, #gpu.thread<linear_dim_0>] }344 gpu.terminator345 }346 return %y : !type347}348 349module attributes {transform.with_named_sequence} {350 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {351 %funcop = transform.structured.match ops{["gpu.launch"]} in %arg0 : (!transform.any_op) -> !transform.any_op352 // expected-error @below {{cannot mix linear and non-linear mapping modes}}353 transform.gpu.map_nested_forall_to_threads %funcop block_dims = [32, 32, 1] : (!transform.any_op) -> !transform.any_op354 transform.yield355 }356}357 358// -----359 360// expected-note @below {{when applied to this payload op}}361module attributes {transform.with_named_sequence} {362 transform.named_sequence @__transform_main(%op: !transform.any_op {transform.consumed}) {363 // expected-error @below {{could not find a unique topLevel scf.forall}}364 %gpu_launch = transform.gpu.map_forall_to_blocks %op generate_gpu_launch grid_dims = [1, 1, 1]365 : (!transform.any_op) -> !transform.any_op366 transform.yield367 }368}369 370// -----371 372func.func public @improperly_sized_grid_dims(%arg0: memref<32x32xf32>, %arg1: memref<32x32xf32>, %arg2: memref<32x32xf32>) {373 scf.forall (%arg3, %arg4) in (1, 1) {374 linalg.matmul ins(%arg0, %arg1 : memref<32x32xf32>, memref<32x32xf32>) outs(%arg2 : memref<32x32xf32>)375 } {mapping = [#gpu.block<x>, #gpu.block<y>]}376 return377}378 379module attributes {transform.with_named_sequence} {380 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.consumed}) {381 %arg0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op382 // expected-error @below {{transform requires empty or size-3 grid_dims}}383 %5 = transform.gpu.map_forall_to_blocks %arg1 generate_gpu_launch grid_dims = [50, 16] : (!transform.any_op) -> !transform.any_op384 transform.yield385 }386}387 388// -----389 390func.func public @missing_mapping_attribute(%arg0: memref<32x32xf32>, %arg1: memref<32x32xf32>, %arg2: memref<32x32xf32>) {391 scf.forall (%arg3, %arg4) in (1, 1) {392 linalg.matmul ins(%arg0, %arg1 : memref<32x32xf32>, memref<32x32xf32>) outs(%arg2 : memref<32x32xf32>)393 }394 return395}396 397module attributes {transform.with_named_sequence} {398 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.consumed}) {399 %arg0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op400 // expected-error @below {{scf.forall op requires a mapping attribute}}401 %5 = transform.gpu.map_forall_to_blocks %arg1 generate_gpu_launch grid_dims = [50, 16, 1] : (!transform.any_op) -> !transform.any_op402 transform.yield403 }404}405 406// -----407 408func.func @masking_mapping_attribute_requires_linear_mapping(409 %x: memref<32xf32>, %y: memref<32xf32>, %t: memref<32 x f32>, %alpha : f32, %stream : !gpu.async.token) -> memref<32xf32> {410 %one = arith.constant 1 : index411 %c9 = arith.constant 9 : index412 %c7 = arith.constant 7 : index413 %name = gpu.launch async[%stream] blocks(%arg3, %arg4, %arg5) in (%arg9 = %one, %arg10 = %one, %arg11 = %one)414 threads(%arg6, %arg7, %arg8) in (%arg12 = %one, %arg13 = %one, %arg14 = %one)415 {416 scf.forall (%i) in (%c7) {417 %4 = memref.load %x[%i] : memref<32xf32>418 %5 = memref.load %y[%i] : memref<32xf32>419 %6 = math.fma %alpha, %4, %5 : f32420 memref.store %6, %y[%i] : memref<32xf32>421 } { mapping = [#gpu.warp<x>, #gpu.mask<0x33>] }422 gpu.terminator423 }424 425 return %y : memref<32xf32>426}427 428module attributes {transform.with_named_sequence} {429 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {430 %funcop = transform.structured.match ops{["gpu.launch"]} in %arg0 : (!transform.any_op) -> !transform.any_op431 // expected-error @below {{device masking is only available in linear mapping mode}}432 transform.gpu.map_nested_forall_to_threads %funcop block_dims = [1, 1, 1] : (!transform.any_op) -> !transform.any_op433 transform.yield434 }435}436 437// -----438 439func.func @masking_mapping_attribute_requires_linear_mapping(440 %x: memref<32xf32>, %y: memref<32xf32>, %t: memref<32 x f32>, %alpha : f32, %stream : !gpu.async.token) -> memref<32xf32> {441 %one = arith.constant 1 : index442 %c99 = arith.constant 99 : index443 %name = gpu.launch async[%stream] blocks(%arg3, %arg4, %arg5) in (%arg9 = %one, %arg10 = %one, %arg11 = %one)444 threads(%arg6, %arg7, %arg8) in (%arg12 = %one, %arg13 = %one, %arg14 = %one)445 {446 scf.forall (%i) in (%c99) {447 %4 = memref.load %x[%i] : memref<32xf32>448 %5 = memref.load %y[%i] : memref<32xf32>449 %6 = math.fma %alpha, %4, %5 : f32450 memref.store %6, %y[%i] : memref<32xf32>451 } { mapping = [#gpu.thread<linear_dim_0>, #gpu.mask<0xff>] }452 gpu.terminator453 }454 455 return %y : memref<32xf32>456}457 458module attributes {transform.with_named_sequence} {459 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {460 %funcop = transform.structured.match ops{["gpu.launch"]} in %arg0 : (!transform.any_op) -> !transform.any_op461 // expected-error @below {{mask representation too short to capture all physical ids: 64}}462 transform.gpu.map_nested_forall_to_threads %funcop block_dims = [128, 1, 1] : (!transform.any_op) -> !transform.any_op463 transform.yield464 }465}466 467// -----468 469func.func public @not_a_block_mapping_attribute(%arg0: memref<32x32xf32>, %arg1: memref<32x32xf32>, %arg2: memref<32x32xf32>) {470 scf.forall (%arg3, %arg4) in (1, 1) {471 linalg.matmul ins(%arg0, %arg1 : memref<32x32xf32>, memref<32x32xf32>) outs(%arg2 : memref<32x32xf32>)472 } {mapping = [#gpu.thread<x>, #gpu.thread<y>]}473 return474}475 476module attributes {transform.with_named_sequence} {477 transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.consumed}) {478 %arg0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op479 // expected-error @below {{scf.forall op requires a mapping attribute of kind 'block'}}480 %5 = transform.gpu.map_forall_to_blocks %arg1 generate_gpu_launch grid_dims = [50, 16, 1] : (!transform.any_op) -> !transform.any_op481 transform.yield482 }483}484 485// -----486 487func.func @not_a_thread_or_warp_mapping_attribute(%x: memref<2 x 32 x f32>, %y: memref<2 x 32 x f32>, %t: memref<32 x f32>, %alpha : f32, %stream : !gpu.async.token) -> memref<2 x 32 x f32> {488 %one = arith.constant 1 : index489 %c900 = arith.constant 900 : index490 %c9 = arith.constant 9 : index491 %c7 = arith.constant 7 : index492 %name = gpu.launch async[%stream] blocks(%arg3, %arg4, %arg5) in (%arg9 = %one, %arg10 = %one, %arg11 = %one)493 threads(%arg6, %arg7, %arg8) in (%arg12 = %one, %arg13 = %one, %arg14 = %one)494 {495 scf.forall (%i, %j) in (%c7, %c900) {496 %4 = memref.load %x[%i, %j] : memref<2 x 32 x f32>497 %5 = memref.load %y[%i, %j] : memref<2 x 32 x f32>498 %6 = math.fma %alpha, %4, %5 : f32499 memref.store %6, %y[%i, %j] : memref<2 x 32 x f32>500 } { mapping = [#gpu.block<y>, #gpu.block<x>] }501 gpu.terminator502 }503 504 return %y : memref<2 x 32 x f32>505}506 507module attributes {transform.with_named_sequence} {508 transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) {509 %funcop = transform.structured.match ops{["gpu.launch"]} in %arg0 : (!transform.any_op) -> !transform.any_op510 // expected-error @below {{scf.forall op requires a mapping attribute of kind 'thread' or 'warp'}}511 transform.gpu.map_nested_forall_to_threads %funcop block_dims = [1, 1, 1] : (!transform.any_op) -> !transform.any_op512 transform.yield513 }514}515