# Passing \`::Type{InconcreteType}\` to CUDA kernel

**URL:** <https://discourse.julialang.org/t/passing-type-inconcretetype-to-cuda-kernel/116833>\
**Category:** GPU\
**Created:** [July 9, 2024, 3:21pm UTC](https://discourse.julialang.org/t/passing-type-inconcretetype-to-cuda-kernel/116833 "2024-07-09T15:21:31Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![hexaeder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hexaeder/32/24403_2.png) [@hexaeder](https://discourse.julialang.org/u/hexaeder)\
**Post date:** [July 9, 2024, 3:21pm UTC](https://discourse.julialang.org/t/passing-type-inconcretetype-to-cuda-kernel/116833/1 "2024-07-09T15:21:31Z")

</div>

Hello,

I have some kernels that share a lot of code but specialize in the end based on some type of `AbstractAction` in the MWE below `Addition` or `Multiplication.` Those concrete actions have some nonbitstype metadata, which is not important in the kernel, so I thought I’d just pass the `Type{<:AbstractAction}` to the GPU kernel rather than the actual object.

Even though `isbitstype(Type{someting}) == false`, there seems to be special handling in the GPU compiler which allows me to pass those objects to the kernel **if** `something` is a concrete type, however it does not work for non-concrete partial types. Hard to explain but, see the MWE below.

Is there a clever way to circumvent this issue? I can only think of

- making up meta data type parameters to “complete” the type even though they don’t do anything,
- creating special dispatch types like `AdditionDispatch` without any type parameters/metadata,

both of which I don’t really like…

```julia
using Pkg
pkg"activate --temp"
pkg"add KernelAbstractions, CUDA"
using KernelAbstractions
using CUDA

abstract type AbstractAction end
struct Addition{M} <: AbstractAction
    meta::M
end
struct Multiplication{M} <: AbstractAction
    meta::M
end

@kernel function kernel!(::Type{T}, z, x, y) where {T<:AbstractAction}
    i = @index(Global)
    z[i] = apply(T, x[i], y[i])
end

@inline apply(::Type{<:Addition}, x, y) = x + y
@inline apply(::Type{<:Multiplication}, x, y) = x * y

x = CuArray(1:10)
y = CuArray(1:10)
z = CuArray(zeros(10))
kernel = kernel!(get_backend(x))

# works on concrete type
kernel(Addition{:foo}, z, x, y; ndrange=length(z))
kernel(Multiplication{:foo}, z, x, y; ndrange=length(z))
isbitstype(Addition{:foo}) # no bitstype!

# does not work on abstract type, tells me its forbidden to pass non-isbits to kernel
kernel(Addition, z, x, y; ndrange=length(z))
kernel(Multiplication, z, x, y; ndrange=length(z))
isbitstype(Addition) # no bitstype!

```

---

<div class="post-metadata">

**Author:** ![maleadt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maleadt/32/10097_2.png) [@maleadt](https://discourse.julialang.org/u/maleadt)\
**Post date:** [July 10, 2024, 4:08pm UTC](https://discourse.julialang.org/t/passing-type-inconcretetype-to-cuda-kernel/116833/2 "2024-07-10T16:08:40Z")

</div>

> [@hexaeder](#):
>
> Even though `isbitstype(Type{someting}) == false`, there seems to be special handling in the GPU compiler which allows me to pass those objects to the kernel

Arguments are allowed if they’re ghost types or const types:

```julia
julia> Core.Compiler.isconstType(Type{Int})
true

julia> Core.Compiler.isconstType(Type{Number})
true

julia> Core.Compiler.isconstType(Type{Array})
false

```

So that doesn’t hold for your incomplete type.

That said, at some point in the past we used to support passing other arguments, as long as they were unused. Some code supporting that remains, [GPUCompiler.jl/src/validation.jl at 85316c7f9f962667121ca8c2455b7a1e5993fd6b · JuliaGPU/GPUCompiler.jl · GitHub](https://github.com/JuliaGPU/GPUCompiler.jl/blob/85316c7f9f962667121ca8c2455b7a1e5993fd6b/src/validation.jl#L76) and [CUDA.jl/src/compiler/execution.jl at 71311afa35463f3fce09ed73bae66f8810b5e821 · JuliaGPU/CUDA.jl · GitHub](https://github.com/JuliaGPU/CUDA.jl/blob/71311afa35463f3fce09ed73bae66f8810b5e821/src/compiler/execution.jl#L251-L258), so if this would work for you, open an issue or have a look at the GPUCompiler.jl git history to add this support back. Looks like it got lost in [Clean-up version checks. · JuliaGPU/GPUCompiler.jl@eec85d5 · GitHub](https://github.com/JuliaGPU/GPUCompiler.jl/commit/eec85d5096370dd4e518e99519e6bd55bd2bf053).

---

<div class="post-metadata">

**Author:** ![hexaeder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hexaeder/32/24403_2.png) [@hexaeder](https://discourse.julialang.org/u/hexaeder)\
**Post date:** [July 11, 2024, 12:04pm UTC](https://discourse.julialang.org/t/passing-type-inconcretetype-to-cuda-kernel/116833/3 "2024-07-11T12:04:32Z")

</div>

Thanks for the explanation! I tried to reenable that feature but turns out to be more difficult now to check if the argument is used inside the kernel. I opened an [issue instead](https://github.com/JuliaGPU/GPUCompiler.jl/issues/597).
