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

copyto!() between cpu and gpu with subarrays #491

Closed
btmit opened this issue Oct 14, 2020 · 4 comments
Closed

copyto!() between cpu and gpu with subarrays #491

btmit opened this issue Oct 14, 2020 · 4 comments

Comments

@btmit
Copy link

btmit commented Oct 14, 2020

Copying a view from the CPU to existing memory on the GPU produces a scalar index error. Copy with the same way CPU-to-CPU and GPU-to-GPU still works.

using CUDA
CUDA.allowscalar(false)

a = zeros(ComplexF32, 4,3,4)
b = CUDA.zeros(ComplexF32, 4,3)

copyto!(b, view(a,:,:,1))

ERROR: scalar setindex! is disallowed

If I try to do the copy with a broadcast

b .= view(a,:,:,1)

I get

ERROR: GPU compilation of kernel broadcast_kernel(CUDA.CuKernelContext, CuDeviceArray{Complex{Float32},2,1}, Base.Broadcast.Broadcasted{Nothing,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}},typeof(identity),Tuple{Base.Broadcast.Extruded{SubArray{Complex{Float32},2,Array{Complex{Float32},3},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true},Tuple{Bool,Bool},Tuple{Int64,Int64}}}}, Int64) failed
KernelError: passing and using non-bitstype argument

@btmit btmit added the bug Something isn't working label Oct 14, 2020
@maleadt
Copy link
Member

maleadt commented Oct 14, 2020

b .= view(a,:,:,1)

This is not supported, you can only have GPU arrays participate in a broadcast. So no CPU array, let alone a CPU view.

copyto!(b, view(a,:,:,1))

This is on purpose, too. We currently only support copying from Array, because there's no easy way to dispatch on dense CPU arrays. There's DenseArray, but that isn't limited to A<:Array:

julia> AbstractGPUArray <: DenseArray
true

And introducing a DenseCPUArray alias like

CUDA.jl/src/array.jl

Lines 148 to 164 in 62ae0c3

# dense arrays: stored contiguously in memory
DenseReinterpretCuArray{T,N,A<:Union{CuArray,ContiguousSubCuArray}} = Base.ReinterpretArray{T,N,S,A} where S
DenseReshapedCuArray{T,N,A<:Union{CuArray,ContiguousSubCuArray,DenseReinterpretCuArray}} = Base.ReshapedArray{T,N,A}
DenseSubCuArray{T,N,A<:Union{CuArray,DenseReshapedCuArray,DenseReinterpretCuArray}} = Base.FastContiguousSubArray{T,N,A}
DenseCuArray{T,N} = Union{CuArray{T,N}, DenseSubCuArray{T,N}, DenseReshapedCuArray{T,N}, DenseReinterpretCuArray{T,N}}
DenseCuVector{T} = DenseCuArray{T,1}
DenseCuMatrix{T} = DenseCuArray{T,2}
DenseCuVecOrMat{T} = Union{DenseCuVector{T}, DenseCuMatrix{T}}
# strided arrays
StridedSubCuArray{T,N,A<:Union{CuArray,DenseReshapedCuArray,DenseReinterpretCuArray},
I<:Tuple{Vararg{Union{Base.RangeIndex, Base.ReshapedUnitRange,
Base.AbstractCartesianIndex}}}} = SubArray{T,N,A,I}
StridedCuArray{T,N} = Union{CuArray{T,N}, StridedSubCuArray{T,N}, DenseReshapedCuArray{T,N}, DenseReinterpretCuArray{T,N}}
StridedCuVector{T} = StridedCuArray{T,1}
StridedCuMatrix{T} = StridedCuArray{T,2}
StridedCuVecOrMat{T} = Union{StridedCuVector{T}, StridedCuMatrix{T}}
would be too hard on the compiler (the current DenseCuArray already has significantly regressed precompilation and load times).

TLDR:

julia> CuArray(view(a,:,:,1))
4×3 CuArray{Complex{Float32},2}:
 0.0+0.0im  0.0+0.0im  0.0+0.0im
 0.0+0.0im  0.0+0.0im  0.0+0.0im
 0.0+0.0im  0.0+0.0im  0.0+0.0im
 0.0+0.0im  0.0+0.0im  0.0+0.0im

@maleadt maleadt closed this as completed Oct 14, 2020
@maleadt maleadt removed the bug Something isn't working label Oct 14, 2020
@btmit
Copy link
Author

btmit commented Oct 14, 2020

Thank you for the information and background.

Is there any way then to copy from a slice of an array on the CPU to pre-allocated memory on the GPU?

@maleadt
Copy link
Member

maleadt commented Oct 14, 2020

You can always unsafe_copyto!(pointer(dst), pointer(src), n), but that's a litttle risky of course.

@ejmeitz
Copy link

ejmeitz commented Jul 25, 2023

Is there a way to copy from GPU into a CPU view?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants