# Arrays of arrays and arrays of structures in CUDA kernels cause random errors

**URL:** <https://discourse.julialang.org/t/arrays-of-arrays-and-arrays-of-structures-in-cuda-kernels-cause-random-errors/69739>\
**Category:** GPU\
**Tags:** gpu, cuda\
**Created:** [October 14, 2021, 10:41am UTC](https://discourse.julialang.org/t/arrays-of-arrays-and-arrays-of-structures-in-cuda-kernels-cause-random-errors/69739 "2021-10-14T10:41:45Z")\
**Posts on this page:** 1\
**Showing post:** 21

<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:** [October 21, 2021, 11:59am UTC](https://discourse.julialang.org/t/arrays-of-arrays-and-arrays-of-structures-in-cuda-kernels-cause-random-errors/69739/21 "2021-10-21T11:59:38Z")

</div>

Here’s a hacky adaptor that does all of the (expensive, as explained above) conversions ahead-of-time:

```julia
using CUDA, Adapt

# dummy class that does complex nesting of CuArrays
struct Nested{T}
	x::T
end
Nested(x::T) where T = Nested{T}(x)
Adapt.adapt_structure(to, nested::Nested) = Nested(adapt(to, nested.x))

# a hacky adaptor that eagerly converts all arrays to GPU device arrays.
# for ownership purposes, the adaptor has a list of roots.
# this means you should keep the adaptor alive until you're done with the adapted values.
struct DeepAdaptor
	roots::Array{CuArray}
	DeepAdaptor() = new(CuArray[])
end
function Adapt.adapt_storage(to::DeepAdaptor, xs::Array)
	y = map(xs) do x
		adapt(to, x)
	end

	# upload to the GPU
	gpu = CuArray(y)

	# immediately convert to a CuDeviceArray, since we can't have CuArray{CuArray}
	push!(to.roots, gpu)
	cudaconvert(gpu)
end

function main()
	x = [Nested([42])]

	to = DeepAdaptor()
	y = adapt(to, x)
	GC.@preserve to begin
		# use y here
		@show typeof(y)
	end
end

```

This successfully converts a `Vector{Nested{Vector{Int64}}}` into a `CuDeviceVector{Nested{CuDeviceVector{Int64, 1}}, 1}` for use on the GPU. You’re responsible for keeping the adaptor alive as long as you use its output values.

---

_[View the full topic](https://discourse.julialang.org/t/arrays-of-arrays-and-arrays-of-structures-in-cuda-kernels-cause-random-errors/69739)._
