There’s several issues with this MWE. First of all, cpu_arr
is a type, not a value. Your MyStruct
should be parametric because Vector
can never live on the GPU. Then there’s the problem of arrays-of-arrays, which doesn’t really work, see Arrays of arrays and arrays of structures in CUDA kernels cause random errors - #12 by fedoroff.
An example how this could work:
using CUDA, Adapt
struct MyStruct{T <: AbstractVector{Tuple{Int,Int}}}
arr::T
end
MyStruct(x::T) where T = MyStruct{T}(x)
Adapt.adapt_structure(to, x::MyStruct) = MyStruct(adapt(to, x.arr))
function main()
cpu_arr = [MyStruct(Vector{Tuple{Int, Int}}())]
# first, convert the contained MyStruct{Vector} elements
gpu_arr = adapt.(CuArray, cpu_arr)
# we could now convert gpu_arr::Vector to a CuArray, but since we'll also have to
# convert the MyStruct{CuArray} elements to MyStruct{CuDeviceArray} (because @cuda
# doesn't automatically convert array _elements_ when calling a kernel), we'll
# leave it on the CPU
GC.@preserve gpu_arr begin
gpu_device_arr = cudaconvert.(gpu_arr)
final_gpu_arr = CuArray(gpu_device_arr)
# final_gpu_arr is now a CuArray of MyStruct{CuDeviceArray} elements, which we can
# pass to a kernel (@cuda will do the outer CuArray->CuDeviceArray conversion)
@show typeof(final_gpu_arr)
end
end
But I recommend simplifying the setup instead.