Non-intuitive difference of copyto! between CuArray and Array

Hi all. I trapped an error when using copyto! to CuArray.
Error is

ERROR: CUDA error: invalid argument (code 1, ERROR_INVALID_VALUE)
Stacktrace:
  [1] throw_api_error(res::CUDA.cudaError_enum)
    @ CUDA ~/.julia/packages/CUDA/Tl08O/lib/cudadrv/libcuda.jl:30
  [2] check
    @ ~/.julia/packages/CUDA/Tl08O/lib/cudadrv/libcuda.jl:37 [inlined]
  [3] cuMemcpyDtoDAsync_v2
    @ ~/.julia/packages/CUDA/Tl08O/lib/utils/call.jl:34 [inlined]
  [4] unsafe_copyto!(dst::CuPtr{Float32}, src::CuPtr{Float32}, N::Int64; stream::CuStream, async::Bool)
    @ CUDA ~/.julia/packages/CUDA/Tl08O/lib/cudadrv/memory.jl:426
  [5] unsafe_copyto!
    @ ~/.julia/packages/CUDA/Tl08O/lib/cudadrv/memory.jl:420 [inlined]
  [6] (::CUDA.var"#1129#1130"{Float32, CuArray{…}, Int64, CuArray{…}, Int64, Int64})()
    @ CUDA ~/.julia/packages/CUDA/Tl08O/src/array.jl:577
  [7] #context!#990
    @ ~/.julia/packages/CUDA/Tl08O/lib/cudadrv/state.jl:168 [inlined]
  [8] context!
    @ ~/.julia/packages/CUDA/Tl08O/lib/cudadrv/state.jl:163 [inlined]
  [9] unsafe_copyto!(dest::CuArray{…}, doffs::Int64, src::CuArray{…}, soffs::Int64, n::Int64)
    @ CUDA ~/.julia/packages/CUDA/Tl08O/src/array.jl:575
 [10] copyto!
    @ ~/.julia/packages/CUDA/Tl08O/src/array.jl:517 [inlined]
 [11] copyto!(dest::CuArray{Float32, 1, CUDA.DeviceMemory}, src::CuArray{Float32, 2, CUDA.DeviceMemory})
    @ CUDA ~/.julia/packages/CUDA/Tl08O/src/array.jl:521
 [12] top-level scope
    @ ~/dev/MR/comm.jl:17
Some type information was truncated. Use `show(err)` to see complete types.

I believe this behavior is a bug because Array copyto! do not throw any error and I think it worked before.

using CUDA
A = CUDA.zeros(16)
B = CUDA.ones(8)
copyto!(A, B)
copyto!(B, A) # This throws error

A = zeros(16)
B = ones(8)
copyto!(A, B)
copyto!(B, A)

This will work. But still I wonder the difference.

using CUDA
A = CUDA.zeros(16)
B = CUDA.ones(8)
copyto!(A, B)
copyto!(B, @views A[1:min(length(A), length(B))])

A = zeros(4, 4)
B = ones(8)
copyto!(A, B)
copyto!(B, @views A[1:min(length(A), length(B))])

The behavior is working as intended, and errors with Array too:

julia> A = zeros(16);

julia> B = ones(8);

julia> copyto!(A, B);

julia> copyto!(B, A);
ERROR: BoundsError: attempt to access 8-element Vector{Float64} at index [1:16]

The fact that you’re getting an ERROR_INVALID_VALUE instead of a bounds error with CUDA.jl reveals that you’re running with --check-bounds=no, which is the problem here.

2 Likes

Thank you and I’m sorry for being so weird.