Skip to content

Unsupported operations in ConvertGPUtoSPIRV #665

@fschlimb

Description

@fschlimb

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<v1.0, [Addresses, Float16Buffer, Int64, Int16, Int8, Bfloat16ConversionINTEL, Kernel, Linkage, Vector16, GenericPointer, Groups, Float16, Float64, AtomicFloat32AddEXT, ExpectAssumeKHR], [SPV_INTEL_bfloat16_conversion, SPV_EXT_shader_atomic_float_add, SPV_KHR_expect_assume]>, 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<i32: 1, 1, 1>, gpu.known_grid_size = array<i32: 5, 1, 1>, 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<v1.0, [Addresses, Float16Buffer, Int64, Int16, Int8, Bfloat16ConversionINTEL, Kernel, Linkage, Vector16, GenericPointer, Groups, Float16, Float64, AtomicFloat32AddEXT, ExpectAssumeKHR], [SPV_INTEL_bfloat16_conversion, SPV_EXT_shader_atomic_float_add, SPV_KHR_expect_assume]>, api=OpenCL, #spirv.resource_limits<>>} {
    gpu.func @test_op_kernel(%arg0: memref<5xf32>, %arg1: memref<5xf32>) kernel attributes {gpu.known_block_size = array<i32: 1, 1, 1>, gpu.known_grid_size = array<i32: 5, 1, 1>, 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
    }
  }
}

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions