diff --git a/src/host/abstractarray.jl b/src/host/abstractarray.jl index 2016f2cb..c05e8b19 100644 --- a/src/host/abstractarray.jl +++ b/src/host/abstractarray.jl @@ -350,6 +350,18 @@ function Base.copyto!(dest::AnyGPUArray{T}, dstart::Integer, return dest end +# `BitArray`s pack their elements into bits, so unpack them on the CPU too +function Base.copyto!(dest::AnyGPUArray{T}, dstart::Integer, + src::BitArray, sstart::Integer, n::Integer) where {T} + n == 0 && return dest + temp = Vector{T}(undef, n) + copyto!(temp, 1, src, sstart, n) + copyto!(dest, dstart, temp, 1, n) + return dest +end + +Base.copyto!(dest::AnyGPUArray, src::BitArray) = copyto!(dest, 1, src, 1, length(src)) + ## generalized blocks of heterogeneous memory # mirrors the checks of Base's `copyto!(dest, Rdest, src, Rsrc)` diff --git a/test/testsuite/base.jl b/test/testsuite/base.jl index 55e2bac1..832b1be4 100644 --- a/test/testsuite/base.jl +++ b/test/testsuite/base.jl @@ -210,6 +210,29 @@ end @test Array(src) == dst end end + + # from a `BitArray`, without scalar indexing (#836) + let src = BitVector([true, false, true, true, false]) + dst = AT{Bool}(undef, length(src)) + copyto!(dst, src) + @test Array(dst) == src + + dst = AT(fill(false, 7)) + copyto!(dst, 2, src, 3, 2) + @test Array(dst) == [false, true, true, false, false, false, false] + + src = BitMatrix([true false; false true]) + dst = AT{Bool}(undef, 2, 2) + copyto!(dst, src) + @test Array(dst) == src + end + if Float32 in eltypes + let src = BitVector([true, false, true]) + dst = AT{Float32}(undef, 3) + copyto!(dst, src) + @test Array(dst) == Float32[1, 0, 1] + end + end end @testset "copyto! of blocks" begin