intel / intel-graphics-compiler

Other
597 stars 155 forks source link

Kernel with by-value array parameter not found in module #163

Closed maleadt closed 2 years ago

maleadt commented 4 years ago

Given the following IR, then compiled with Khronos' LLVM to SPIRV translator:

; ModuleID = 'julia'
source_filename = "julia"
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
target triple = "spir64-unknown-unknown"

define dso_local spir_kernel void @kernel([1 x i64] addrspace(1)* byval) local_unnamed_addr {
top:
  ret void
}

!llvm.module.flags = !{!0, !1}
!opencl.ocl.version = !{!3}
!opencl.spirv.version = !{!4}

!0 = !{i32 2, !"Dwarf Version", i32 4}
!1 = !{i32 1, !"Debug Info Version", i32 3}
!3 = !{i32 2, i32 0}
!4 = !{i32 1, i32 5}
               OpCapability Addresses
               OpCapability Kernel
               OpCapability Int64
          %1 = OpExtInstImport "OpenCL.std"
               OpMemoryModel Physical64 OpenCL
               OpEntryPoint Kernel %8 "kernel"
               OpSource OpenCL_C 200000
               OpName %top "top"
               OpDecorate %9 FuncParamAttr ByVal
      %ulong = OpTypeInt 64 0
    %ulong_1 = OpConstant %ulong 1
       %void = OpTypeVoid
%_arr_ulong_ulong_1 = OpTypeArray %ulong %ulong_1
%_ptr_CrossWorkgroup__arr_ulong_ulong_1 = OpTypePointer CrossWorkgroup %_arr_ulong_ulong_1
          %7 = OpTypeFunction %void %_ptr_CrossWorkgroup__arr_ulong_ulong_1
          %8 = OpFunction %void None %7
          %9 = OpFunctionParameter %_ptr_CrossWorkgroup__arr_ulong_ulong_1
        %top = OpLabel
               OpReturn
               OpFunctionEnd

I can successfully load this module (zeModuleCreate) and iterate the kernels (zeModuleGetKernelNames) to get kernel.

If I change the function argument to take an array by value, instead of a pointer with the ByVal attribute:

define dso_local spir_kernel void @kernel([1 x i64]) local_unnamed_addr {
top:
  ret void
}
               OpCapability Addresses
               OpCapability Kernel
               OpCapability Int64
          %1 = OpExtInstImport "OpenCL.std"
               OpMemoryModel Physical64 OpenCL
               OpEntryPoint Kernel %7 "kernel"
               OpSource OpenCL_C 200000
               OpName %top "top"
      %ulong = OpTypeInt 64 0
    %ulong_1 = OpConstant %ulong 1
       %void = OpTypeVoid
%_arr_ulong_ulong_1 = OpTypeArray %ulong %ulong_1
          %6 = OpTypeFunction %void %_arr_ulong_ulong_1
          %7 = OpFunction %void None %6
          %8 = OpFunctionParameter %_arr_ulong_ulong_1
        %top = OpLabel
               OpReturn
               OpFunctionEnd

Now zeModuleGetKernelNames returns an empty set.

jchodor commented 4 years ago
  1. It's a bug that zeModuleCreate didn't fail with proper error message
  2. It's not allowed to use OpTypeArray as function parameter in level_zero : https://spec.oneapi.com/level-zero/latest/core/SPIRV.html#kernel-arguments : ` Kernel Arguments

An OpFunctionParameter for an OpFunction that is identified with OpEntryPoint defines a kernel argument. Allowed types for kernel arguments are:

OpTypeInt

OpTypeFloat

OpTypeStruct

OpTypeVector

OpTypePointer

OpTypeSampler

OpTypeImage `

  1. The reason why the non-ByVal version worked is that array got treated as pointer "%_ptr_CrossWorkgroup__arr_ulong_ulong_1 = OpTypePointer CrossWorkgroup %_arr_ulong_ulong_1".

  2. Can you try wrapping the array with a struct or using vector types?

maleadt commented 4 years ago

The reason why the non-ByVal version worked is that array got treated as pointer "%_ptr_CrossWorkgroup__arr_ulong_ulong_1 = OpTypePointer CrossWorkgroup %_arr_ulong_ulong_1".

It's the inverse: the case that works is a OpTypePointer with the ByVal attribute. It's the non-ByVal version where I don't use a pointer but actually pass a value that doesn't (because that's not supported, apparently).

Anyway, if passing a OpTypeArray isn't supported, but doing so as a OpTypePointer with the ByVal attribute set is (which should boil down to exactly the same code, so I don't really get the difference), that works for me. I'd rather not start wrapping stuff in structs or vector types.

What remains of this issue then is just the reporting by zeModuleCreate.

JacekDanecki commented 3 years ago

I'm transferring this issue to IGC project: https://github.com/intel/intel-graphics-compiler

mnaczk commented 2 years ago

Thanks, @maleadt for spotting the issue. The commit https://github.com/intel/intel-graphics-compiler/commit/c389eb9c7b518fde6ceba9b4e47b39599782b529 add the error message if we get unsupported type as Kernel argument.