Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapt + strictly-typed fields can trigger confusing errors #2384

Open
maleadt opened this issue May 15, 2024 · 0 comments
Open

Adapt + strictly-typed fields can trigger confusing errors #2384

maleadt opened this issue May 15, 2024 · 0 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@maleadt
Copy link
Member

maleadt commented May 15, 2024

Say, a user wants to pass a struct with CuArrays to the GPU:

julia> struct Foo
       x::CuVector{Float32}
       end

julia> @cuda Returns(nothing)(Foo(CUDA.rand(1)))
ERROR: GPU compilation of MethodInstance for (::Returns{Nothing})(::Foo) failed
KernelError: passing and using non-bitstype argument

We may tell him to define an Adapt rule to convert the CuArray to CuDeviceArray. However, because the field isn't parametric, that triggers a very confusing error:

julia> Adapt.@adapt_structure Foo

julia> @cuda Returns(nothing)(Foo(CUDA.rand(1)))
ERROR: This function is not intended for use on the CPU
Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:35
  [2] arrayref(A::CuDeviceVector{Float32, 1}, index::Int64)
    @ CUDA ~/Julia/pkg/CUDA/src/device/utils.jl:29
  [3] getindex
    @ ~/Julia/pkg/CUDA/src/device/array.jl:164 [inlined]
  [4] copyto_unaliased!
    @ ./abstractarray.jl:1088 [inlined]
  [5] copyto!
    @ ./abstractarray.jl:1068 [inlined]
  [6] copyto_axcheck!
    @ ./abstractarray.jl:1177 [inlined]
  [7] Array
    @ ./array.jl:673 [inlined]
  [8] Array
    @ ./boot.jl:501 [inlined]
  [9] convert
    @ ./array.jl:665 [inlined]
 [10] CuArray
    @ ~/Julia/pkg/CUDA/src/array.jl:406 [inlined]
 [11] CuArray
    @ ~/Julia/pkg/CUDA/src/array.jl:410 [inlined]
 [12] convert(::Type{CuArray{Float32, 1}}, a::CuDeviceVector{Float32, 1})
    @ GPUArrays ~/Julia/pkg/GPUArrays/src/host/construction.jl:4
 [13] Foo
    @ ./REPL[5]:2 [inlined]
 [14] adapt_structure(to::CUDA.KernelAdaptor, obj::Foo)
    @ Main ~/Julia/pkg/Adapt/src/macro.jl:11
 [15] adapt
    @ ~/Julia/pkg/Adapt/src/Adapt.jl:40 [inlined]
 [16] cudaconvert
    @ ~/Julia/pkg/CUDA/src/compiler/execution.jl:198 [inlined]
 [17] map(f::typeof(cudaconvert), t::Tuple{Foo})
    @ Base ./tuple.jl:291
 [18] top-level scope
    @ ~/Julia/pkg/CUDA/src/compiler/execution.jl:110

I'm not sure it makes sense to try and convert fields that aren't parametric (because it would just convert the values back again). So either we fix this in Adapt, or we provide some convert implementation that errors early and makes the issue more clear.

FWIW, to fix the actual issue the field needs to be parametric:

julia> struct Bar{T<:AbstractArray}
       x::T
       end

julia> Adapt.@adapt_structure Bar

julia> @cuda Returns(nothing)(Bar(CUDA.rand(1)))
@maleadt maleadt added enhancement New feature or request good first issue Good for newcomers labels May 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

1 participant