Isbits union support in CUDA.jl

I’m confused about the support that CUDA.jl has for isbits unions:

# Unions of two work fine:
map(x->1, CuVector([1,missing]));
map(x->1, CuVector([1,nothing]));

# It is possible to move unions of three to the GPU memory
CuVector([1,missing,nothing]);

# But compiling a GPU kernel fails...
map(x->1, CuVector([1,missing,nothing]));
# unsupported dynamic function invocation (call to arrayref_union(A::CuDeviceArray{T, AS, A} where A, index::Integer) where {T, AS} in CUDA)

# The restriction seems to be on the size of the type union, 
# not on the size of the isbits array elements
# for example, this works fine:
struct Big
    x::Int
    y::Bool
    z::Int
    w::Float32
end
map(x->1, CuVector([Big(1,true,2,0.5), Big(2,false,3,0.2), missing]));

When I want CUDA.jl to work with a union of >2 things, the best solution is to make a custom overarching isbits struct where I manually add type selector bytes?

That’s a bug, please file an issue on the CUDA.jl repository. Union support is relatively new, so there may still be bugs.

2 Likes

Thanks, issue filed: unsupported dynamic function invocation with union type of more than 2 elements · Issue #1252 · JuliaGPU/CUDA.jl · GitHub