JuliaGPU / JuliaGPU/KernelAbstractions.jl
tuples with multiple functions cannot be accessed on the GPU with a complicated symbol
Open
Nobody has claimed this yet.
- Dominant language
- Julia
- Stars
- 523
- Forks
- 88
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 25
Description
MWE:
using KernelAbstractions, CUDA, CUDAKernels
@kernel function f_test_kernel!(input, tuple_thingy, tuple_size)
tid = @index(Global, Linear)
meh = tid%tuple_size+1
input[tid] = tuple_thingy[meh](tid)
end
function test!(input, tuple_thingy, tuple_size; numcores = 4, numthreads = 256)
if isa(input, Array)
kernel! = f_test_kernel!(CPU(), numcores)
else
kernel! = f_test_kernel!(CUDADevice(), numthreads)
end
kernel!(input, tuple_thingy, tuple_size, ndrange=size(input)[1])
end
f(x) = x+1
g(x) = x+2
h(x) = x+3
input = zeros(1024)
tuple_thingy = (f,g,h)
tuple_size = 3
wait(test!(input, tuple_thingy, tuple_size))
d_input = CuArray(zeros(1024))
wait(test!(d_input, tuple_thingy, tuple_size))
Error:
ERROR: LoadError: InvalidIRError: compiling kernel gpu_f_test_kernel!(Cassette.Context{nametype(CUDACtx), Nothing,
Nothing, KernelAbstractions.var"##PassType#274", Nothing, Cassette.DisableHooks}, typeof(gpu_f_test_kernel!),
KernelAbstractions.CompilerMetadata{KernelAbstractions.NDIteration.DynamicSize,
KernelAbstractions.NDIteration.DynamicCheck, Nothing, CartesianIndices{1, Tuple{Base.OneTo{Int64}}},
KernelAbstractions.NDIteration.NDRange{1, KernelAbstractions.NDIteration.DynamicSize,
KernelAbstractions.NDIteration.StaticSize{(256,)}, CartesianIndices{1, Tuple{Base.OneTo{Int64}}}, Nothing}},
CuDeviceVector{Float64, 1}, Tuple{typeof(f), typeof(g), typeof(h)}, Int64) resulted in invalid LLVM IR
Reason: unsupported call to an unknown function (call to jl_f_getfield)
Stacktrace:
[1] getindex(::Tuple{typeof(f), typeof(g), typeof(h)}, ::Int64)
@ ./tuple.jl:29
[2] overdub
@ ./tuple.jl:29
[3] macro expansion
@ ~/projects/simuleios/test/tuple_test.jl:7
[4] overdub
@ ~/projects/KernelAbstractions.jl/src/macros.jl:80
[5] overdub
@ ~/.julia/packages/Cassette/1lyEM/src/overdub.jl:0
Stacktrace:
[1] check_ir(job::GPUCompiler.CompilerJob{GPUCompiler.PTXCompilerTarget, CUDA.CUDACompilerParams,
GPUCompiler.FunctionSpec{typeof(Cassette.overdub), Tuple{Cassette.Context{nametype(CUDACtx), Nothing, Nothing,
KernelAbstractions.var"##PassType#274", Nothing, Cassette.DisableHooks}, typeof(gpu_f_test_kernel!),
KernelAbstractions.CompilerMetadata{KernelAbstractions.NDIteration.DynamicSize,
KernelAbstractions.NDIteration.DynamicCheck, Nothing, CartesianIndices{1, Tuple{Base.OneTo{Int64}}},
KernelAbstractions.NDIteration.NDRange{1, KernelAbstractions.NDIteration.DynamicSize,
KernelAbstractions.NDIteration.StaticSize{(256,)}, CartesianIndices{1, Tuple{Base.OneTo{Int64}}}, Nothing}},
CuDeviceVector{Float64, 1}, Tuple{typeof(f), typeof(g), typeof(h)}, Int64}}}, args::LLVM.Module)
@ GPUCompiler ~/.julia/packages/GPUCompiler/HeCT6/src/validation.jl:111
[2] macro expansion
@ ~/.julia/packages/GPUCompiler/HeCT6/src/driver.jl:326 [inlined]
[3] macro expansion
@ ~/.julia/packages/TimerOutputs/SSeq1/src/TimerOutput.jl:252 [inlined]
[4] macro expansion
@ ~/.julia/packages/GPUCompiler/HeCT6/src/driver.jl:324 [inlined]
[5] emit_asm(job::GPUCompiler.CompilerJob, ir::LLVM.Module; strip::Bool, validate::Bool, format::LLVM.API.LLVMCodeGenFileType)
@ GPUCompiler ~/.julia/packages/GPUCompiler/HeCT6/src/utils.jl:64
[6] cufunction_compile(job::GPUCompiler.CompilerJob)
@ CUDA ~/.julia/packages/CUDA/sCev8/src/compiler/execution.jl:326
[7] cached_compilation(cache::Dict{UInt64, Any}, job::GPUCompiler.CompilerJob, compiler::typeof(CUDA.cufunction_compile), linker::typeof(CUDA.cufunction_link))
@ GPUCompiler ~/.julia/packages/GPUCompiler/HeCT6/src/cache.jl:90
[8] cufunction(f::typeof(Cassette.overdub), tt::Type{Tuple{Cassette.Context{nametype(CUDACtx), Nothing, Nothing,
KernelAbstractions.var"##PassType#274", Nothing, Cassette.DisableHooks}, typeof(gpu_f_test_kernel!),
KernelAbstractions.CompilerMetadata{KernelAbstractions.NDIteration.DynamicSize,
KernelAbstractions.NDIteration.DynamicCheck, Nothing, CartesianIndices{1, Tuple{Base.OneTo{Int64}}},
KernelAbstractions.NDIteration.NDRange{1, KernelAbstractions.NDIteration.DynamicSize,
KernelAbstractions.NDIteration.StaticSize{(256,)}, CartesianIndices{1, Tuple{Base.OneTo{Int64}}}, Nothing}},
CuDeviceVector{Float64, 1}, Tuple{typeof(f), typeof(g), typeof(h)}, Int64}}; name::String, kwargs::Base.Pairs{Symbol, Union{},
Tuple{}, NamedTuple{(), Tuple{}}})
@ CUDA ~/.julia/packages/CUDA/sCev8/src/compiler/execution.jl:297
[9] macro expansion
@ ~/.julia/packages/CUDA/sCev8/src/compiler/execution.jl:102 [inlined]
[10] (::KernelAbstractions.Kernel{CUDADevice, KernelAbstractions.NDIteration.StaticSize{(256,)},
KernelAbstractions.NDIteration.DynamicSize, typeof(gpu_f_test_kernel!)})(::CuArray{Float64, 1, CUDA.Mem.DeviceBuffer},
::Vararg{Any}; ndrange::Int64, dependencies::CUDAKernels.CudaEvent, workgroupsize::Nothing, progress::Function)
@ CUDAKernels ~/projects/KernelAbstractions.jl/lib/CUDAKernels/src/CUDAKernels.jl:194
[11] test!(input::CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, tuple_thingy::Tuple{typeof(f), typeof(g), typeof(h)},
tuple_size::Int64; numcores::Int64, numthreads::Int64)
@ Main ~/projects/simuleios/test/tuple_test.jl:18
[12] test!(input::CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, tuple_thingy::Tuple{typeof(f), typeof(g), typeof(h)},
tuple_size::Int64)
@ Main ~/projects/simuleios/test/tuple_test.jl:12
[13] top-level scope
@ ~/projects/simuleios/test/tuple_test.jl:33
[14] include(fname::String)
@ Base.MainInclude ./client.jl:451
[15] top-level scope
@ REPL[1]:1
in expression starting at /home/leios/projects/simuleios/test/tuple_test.jl:33
Notes:
- If
mehis1or set to a specific integer, there is no error. - This seems to fall back to
@eval getindex(@nospecialize(t::Tuple), i::Int) = getfield(t, i, $(Expr(:boundscheck))), so I tried with@inbounds(as that was the only thing I could think of), but I got the same error - If the tuple all has the same function, there is no error
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the MWE in test/tuple_test.jl and compare the CPU and CUDA paths. Trace the tuple indexing through src/macros.jl and lib/CUDAKernels/src/CUDAKernels.jl, using the reported invalid LLVM IR as the failure point. Done means a GPU kernel can index a tuple containing multiple functions without this compilation error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- julia
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100