Hi,
I have a problem with passing a tuple of structs to a CUDA.jl kernel.
This is MWE:
using CUDA, Adapt, StaticArrays
struct MyType1 end
struct MyType2 end
struct MyStruct{T,N,L}
type :: T
data :: SMatrix{N,2,Float64,L}
end
Adapt.@adapt_structure MyStruct # this is not required probably
s1 = MyStruct(MyType1(), SMatrix{100,2}(rand(100,2)))
s2 = MyStruct(MyType2(), SMatrix{100,2}(rand(100,2)))
t = (s1,s2)
isbits(t) #true
function kernel(t)
@cushow t[threadIdx().x].data[1,1]
return nothing
end
@cuda threads=2 kernel(t)
but I am getting an error:
InvalidIRError: compiling kernel kernel(Tuple{MyStruct{MyType1, 100, 200}, MyStruct{MyType2, 100, 200}}) resulted in invalid LLVM IR
Reason: unsupported call to an unknown function (call to jl_f_getfield)
Stacktrace:
[1] getindex
@ .\tuple.jl:30
[2] macro expansion
@ C:\Users\lodygaw\.julia\packages\CUDA\Y6ceW\src\device\intrinsics\output.jl:248
[3] kernel
@ .\In[19]:19
Hint: catch this exception as `err` and call `code_typed(err; interactive = true)` to introspect the erronous code
Stacktrace:
[1] check_ir(job::GPUCompiler.CompilerJob{GPUCompiler.PTXCompilerTarget, CUDA.CUDACompilerParams, GPUCompiler.FunctionSpec{typeof(kernel), Tuple{Tuple{MyStruct{MyType1, 100, 200}, MyStruct{MyType2, 100, 200}}}}}, args::LLVM.Module)
@ GPUCompiler C:\Users\lodygaw\.julia\packages\GPUCompiler\1FdJy\src\validation.jl:124
[2] macro expansion
@ C:\Users\lodygaw\.julia\packages\GPUCompiler\1FdJy\src\driver.jl:386 [inlined]
[3] macro expansion
@ C:\Users\lodygaw\.julia\packages\TimerOutputs\nDhDw\src\TimerOutput.jl:252 [inlined]
[4] macro expansion
@ C:\Users\lodygaw\.julia\packages\GPUCompiler\1FdJy\src\driver.jl:384 [inlined]
[5] emit_asm(job::GPUCompiler.CompilerJob, ir::LLVM.Module; strip::Bool, validate::Bool, format::LLVM.API.LLVMCodeGenFileType)
@ GPUCompiler C:\Users\lodygaw\.julia\packages\GPUCompiler\1FdJy\src\utils.jl:64
[6] cufunction_compile(job::GPUCompiler.CompilerJob, ctx::LLVM.Context)
@ CUDA C:\Users\lodygaw\.julia\packages\CUDA\Y6ceW\src\compiler\execution.jl:332
[7] #260
@ C:\Users\lodygaw\.julia\packages\CUDA\Y6ceW\src\compiler\execution.jl:325 [inlined]
[8] JuliaContext(f::CUDA.var"#260#261"{GPUCompiler.CompilerJob{GPUCompiler.PTXCompilerTarget, CUDA.CUDACompilerParams, GPUCompiler.FunctionSpec{typeof(kernel), Tuple{Tuple{MyStruct{MyType1, 100, 200}, MyStruct{MyType2, 100, 200}}}}}})
@ GPUCompiler C:\Users\lodygaw\.julia\packages\GPUCompiler\1FdJy\src\driver.jl:74
[9] cufunction_compile(job::GPUCompiler.CompilerJob)
@ CUDA C:\Users\lodygaw\.julia\packages\CUDA\Y6ceW\src\compiler\execution.jl:324
[10] cached_compilation(cache::Dict{UInt64, Any}, job::GPUCompiler.CompilerJob, compiler::typeof(CUDA.cufunction_compile), linker::typeof(CUDA.cufunction_link))
@ GPUCompiler C:\Users\lodygaw\.julia\packages\GPUCompiler\1FdJy\src\cache.jl:90
[11] cufunction(f::typeof(kernel), tt::Type{Tuple{Tuple{MyStruct{MyType1, 100, 200}, MyStruct{MyType2, 100, 200}}}}; name::Nothing, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ CUDA C:\Users\lodygaw\.julia\packages\CUDA\Y6ceW\src\compiler\execution.jl:297
[12] cufunction(f::typeof(kernel), tt::Type{Tuple{Tuple{MyStruct{MyType1, 100, 200}, MyStruct{MyType2, 100, 200}}}})
@ CUDA C:\Users\lodygaw\.julia\packages\CUDA\Y6ceW\src\compiler\execution.jl:291
[13] top-level scope
@ C:\Users\lodygaw\.julia\packages\CUDA\Y6ceW\src\compiler\execution.jl:102
[14] eval
@ .\boot.jl:373 [inlined]
[15] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
@ Base .\loading.jl:1196
It seems quite basic to me but maybe it is not supported?