Unsupported operations in ConvertGPUtoSPIRV
- Dominant language
- MLIR
- Stars
- 156
- Forks
- 45
- Avg merge
- 4h 14m
- Merged PRs (30d)
- 22
Description
`bin/imex-opt -imex-convert-gpu-to-spirv` on the below IR fails with the error message
`error: failed to legalize operation 'math.ipowi'`
```
module attributes {gpu.container_module} {
func.func private @printMemrefI32(memref<*xi32>)
func.func @test_op(%arg0: memref<5xi32, strided<[?], offset: ?>>, %arg1: memref<5xi32, strided<[?], offset: ?>>) {
%c5 = arith.constant 5 : index
%c1 = arith.constant 1 : index
%memref = gpu.alloc host_shared () : memref<5xi32>
memref.copy %arg1, %memref : memref<5xi32, strided<[?], offset: ?>> to memref<5xi32>
%cast = memref.cast %memref : memref<5xi32> to memref<5xi32, strided<[?], offset: ?>>
%memref_0 = gpu.alloc host_shared () : memref<5xi32>
memref.copy %arg0, %memref_0 : memref<5xi32, strided<[?], offset: ?>> to memref<5xi32>
%cast_1 = memref.cast %memref_0 : memref<5xi32> to memref<5xi32, strided<[?], offset: ?>>
%memref_2 = gpu.alloc host_shared () : memref<5xi32>
gpu.launch_func @test_op_kernel::@test_op_kernel blocks in (%c5, %c1, %c1) threads in (%c1, %c1, %c1) args(%memref_0 : memref<5xi32>, %memref : memref<5xi32>, %memref_2 : memref<5xi32>)
%cast_3 = memref.cast %memref_2 : memref<5xi32> to memref<*xi32>
call @printMemrefI32(%cast_3) : (memref<*xi32>) -> ()
gpu.dealloc %cast_1 : memref<5xi32, strided<[?], offset: ?>>
gpu.dealloc %cast : memref<5xi32, strided<[?], offset: ?>>
return
}
gpu.module @test_op_kernel attributes {spirv.target_env = #spirv.target_env<#spirv.vce, api=OpenCL, #spirv.resource_limits<>>} {
gpu.func @test_op_kernel(%arg0: memref<5xi32>, %arg1: memref<5xi32>, %arg2: memref<5xi32>) kernel attributes {gpu.known_block_size = array, gpu.known_grid_size = array, spirv.entry_point_abi = #spirv.entry_point_abi<>} {
%0 = gpu.block_id x
%1 = memref.load %arg0[%0] : memref<5xi32>
%2 = memref.load %arg1[%0] : memref<5xi32>
%3 = math.ipowi %1, %2 : i32
memref.store %3, %arg2[%0] : memref<5xi32>
gpu.return
}
}
}
```
The same happens when using `math.atan2` (using f32 memrefs).
Similarly, some unary operations are not supported (see example IR below):
- `math.atan`
- `math.tan`
- `math.log2`
- `math.log10`
```
module attributes {gpu.container_module} {
func.func private @printMemrefF32(memref<*xf32>)
func.func @test_op(%arg0: memref<5xf32, strided<[?], offset: ?>>) {
%c5 = arith.constant 5 : index
%c1 = arith.constant 1 : index
%memref = gpu.alloc host_shared () : memref<5xf32>
memref.copy %arg0, %memref : memref<5xf32, strided<[?], offset: ?>> to memref<5xf32>
%cast = memref.cast %memref : memref<5xf32> to memref<5xf32, strided<[?], offset: ?>>
%memref_0 = gpu.alloc host_shared () : memref<5xf32>
gpu.launch_func @test_op_kernel::@test_op_kernel blocks in (%c5, %c1, %c1) threads in (%c1, %c1, %c1) args(%memref : memref<5xf32>, %memref_0 : memref<5xf32>)
%cast_1 = memref.cast %memref_0 : memref<5xf32> to memref<*xf32>
call @printMemrefF32(%cast_1) : (memref<*xf32>) -> ()
gpu.dealloc %cast : memref<5xf32, strided<[?], offset: ?>>
return
}
gpu.module @test_op_kernel attributes {spirv.target_env = #spirv.target_env<#spirv.vce, api=OpenCL, #spirv.resource_limits<>>} {
gpu.func @test_op_kernel(%arg0: memref<5xf32>, %arg1: memref<5xf32>) kernel attributes {gpu.known_block_size = array, gpu.known_grid_size = array, spirv.entry_point_abi = #spirv.entry_point_abi<>} {
%0 = gpu.block_id x
%1 = memref.load %arg0[%0] : memref<5xf32>
%2 = math.tan %1 : f32
memref.store %2, %arg1[%0] : memref<5xf32>
gpu.return
}
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.