# ArgumentError: cannot take the CPU address of a CuArray when using selectdim

**URL:** <https://discourse.julialang.org/t/argumenterror-cannot-take-the-cpu-address-of-a-cuarray-when-using-selectdim/37281>\
**Category:** GPU\
**Tags:** question\
**Created:** [April 9, 2020, 2:35pm UTC](https://discourse.julialang.org/t/argumenterror-cannot-take-the-cpu-address-of-a-cuarray-when-using-selectdim/37281 "2020-04-09T14:35:07Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Geoffrey](https://avatars.discourse-cdn.com/v4/letter/g/bc8723/32.png) [@Geoffrey](https://discourse.julialang.org/u/Geoffrey)\
**Post date:** [April 9, 2020, 2:35pm UTC](https://discourse.julialang.org/t/argumenterror-cannot-take-the-cpu-address-of-a-cuarray-when-using-selectdim/37281/1 "2020-04-09T14:35:07Z")

</div>

Hi,  
I’m quite new to Julia computing and even more to GPU computing but I notice that selectdim function from julia output is stored on the CPU acording to this error: “ERROR: ArgumentError: cannot take the CPU address of a CuArray{Float32,2,Nothing}” when running this MWE:

```julia
a = CuArrays.rand(3,5)
a*selectdim(a,1,1)

```

```julia
ERROR: ArgumentError: cannot take the CPU address of a CuArray{Float32,2,Nothing}
Stacktrace:
 [1] unsafe_convert(::Type{Ptr{Float32}}, ::CuArray{Float32,2,Nothing}) at C:\Users\geoff\.juliapro\JuliaPro_v1.3.1-2\packages\CuArrays\e8PLr\src\array.jl:226
 [2] gemv!(::Char, ::Bool, ::CuArray{Float32,2,Nothing}, ::SubArray{Float32,1,CuArray{Float32,2,Nothing},Tuple{Int64,Base.Slice{Base.OneTo{Int64}}},true}, ::Bool, ::CuArray{Float32,1,Nothing}) at C:\Users\julia\AppData\Local\Julia-1.3.1\share\julia\stdlib\v1.3\LinearAlgebra\src\blas.jl:587
 [3] gemv!(::CuArray{Float32,1,Nothing}, ::Char, ::CuArray{Float32,2,Nothing}, ::SubArray{Float32,1,CuArray{Float32,2,Nothing},Tuple{Int64,Base.Slice{Base.OneTo{Int64}}},true}, ::Bool, ::Bool) at C:\Users\julia\AppData\Local\Julia-1.3.1\share\julia\stdlib\v1.3\LinearAlgebra\src\matmul.jl:463
 [4] mul! at C:\Users\julia\AppData\Local\Julia-1.3.1\share\julia\stdlib\v1.3\LinearAlgebra\src\matmul.jl:66 [inlined]
 [5] mul! at C:\Users\julia\AppData\Local\Julia-1.3.1\share\julia\stdlib\v1.3\LinearAlgebra\src\matmul.jl:203 [inlined]
 [6] *(::CuArray{Float32,2,Nothing}, ::SubArray{Float32,1,CuArray{Float32,2,Nothing},Tuple{Int64,Base.Slice{Base.OneTo{Int64}}},true}) at C:\Users\julia\AppData\Local\Julia-1.3.1\share\julia\stdlib\v1.3\LinearAlgebra\src\matmul.jl:47
 [7] top-level scope at none:0

```

Has I understand I need to transfert the output of selectdim to GPU as this work:

```julia
a*CuArray(selectdim(a,1,1))

```

But I want this part of my code to work on CPU when a is on CPU and to work on GPU otherwise, is this possible ?

Thanks in advance for your help,  
Geoffrey

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [April 9, 2020, 3:23pm UTC](https://discourse.julialang.org/t/argumenterror-cannot-take-the-cpu-address-of-a-cuarray-when-using-selectdim/37281/2 "2020-04-09T15:23:29Z")

</div>

I don’t have a great solution, except that using `a[1,:]` or `copy(selectdim(a,1,1))` ought to work on both.

Some views of `CuArray`s are themselves `CuArray`s, and many GPU functions demand this type. The fact that yours isn’t is why it’s going to a CPU routine, and the fact that it’s still a `StridedArray` is why it’s going to a routine which wants a pointer, not a generic fallback (which would give scalar indexing errors instead). Perhaps this could all be done differently but this is the present design.

```julia
julia> view(a,1,:) |> typeof # as in question
SubArray{Float32,1,CuArray{Float32,2,Nothing},Tuple{Int64,Base.Slice{Base.OneTo{Int64}}},true}

julia> view(a,1,:) isa StridedArray
true

julia> view(a,:,1) |> typeof # first dimension has stride 1
CuArray{Float32,1,CuArray{Float32,2,Nothing}}

julia> @which mul!(similar(a, size(a,1)), a, a[1, :], true, false) # GPU method wants all CuArrays 
mul!(Y::CuArray{T,1,P} where P, A::CuArray{T,2,P} where P, B::CuArray{T,1,P} where P, a::Union{Bool, T}, b::Union{Bool, T}) where T<:Union{Complex{Float32}, Complex{Float64}, Float32, Float64} in CuArrays.CUBLAS at /Users/me/.julia/dev/CuArrays/src/blas/linalg.jl:95

```

---

<div class="post-metadata">

**Author:** ![Geoffrey](https://avatars.discourse-cdn.com/v4/letter/g/bc8723/32.png) [@Geoffrey](https://discourse.julialang.org/u/Geoffrey)\
**Post date:** [April 10, 2020, 3:03pm UTC](https://discourse.julialang.org/t/argumenterror-cannot-take-the-cpu-address-of-a-cuarray-when-using-selectdim/37281/3 "2020-04-10T15:03:59Z")

</div>

@mcabbott thank you copy() work work just fine ! But for the sake of my understanding of Julia programming do you know why view() return an array on the CPU from an array in the GPU ? I thought that view() doesn’t create new allocation when called.

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [April 10, 2020, 4:05pm UTC](https://discourse.julialang.org/t/argumenterror-cannot-take-the-cpu-address-of-a-cuarray-when-using-selectdim/37281/4 "2020-04-10T16:05:07Z")

</div>

Right, view makes a view, which internally is (almost always) the `SubArray` type, and `SubArray{Float32,1,CuArray{...` indicates the underlying type – it isn’t on the CPU. If you write into this you will change `a`.

But what’s happening is that `*` does not end up calling the method designed for CuArrays, and instead falls back to one (of several) intended for CPU arrays, which doesn’t work.

It goes there because signature of the CuArrays `mul!` method does not allow for `SubArray{...,CuArray}`. But whether that method could actually handle this case or not, I’m not sure. It’s more difficult than `view(a,:,1)` because that has stride 1 on the first index (like `strides(a)` does), and this may be a requirement of the implementation of `mul!`.

---

<div class="post-metadata">

**Author:** ![Geoffrey](https://avatars.discourse-cdn.com/v4/letter/g/bc8723/32.png) [@Geoffrey](https://discourse.julialang.org/u/Geoffrey)\
**Post date:** [April 10, 2020, 5:06pm UTC](https://discourse.julialang.org/t/argumenterror-cannot-take-the-cpu-address-of-a-cuarray-when-using-selectdim/37281/5 "2020-04-10T17:06:11Z")

</div>

Oh right I get it, many thanks for your explanation !
