# Indexing 2D CuArray

**URL:** <https://discourse.julialang.org/t/indexing-2d-cuarray/64825>\
**Category:** General Usage\
**Created:** [July 17, 2021, 7:03pm UTC](https://discourse.julialang.org/t/indexing-2d-cuarray/64825 "2021-07-17T19:03:14Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![vavrines](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vavrines/32/8024_2.png) [@vavrines](https://discourse.julialang.org/u/vavrines)\
**Post date:** [July 17, 2021, 7:03pm UTC](https://discourse.julialang.org/t/indexing-2d-cuarray/64825/1 "2021-07-17T19:03:14Z")

</div>

I’m learning to use CUDA.jl based on the [tutorial](https://cuda.juliagpu.org/stable/tutorials/introduction/), and trying to write a kernel for 2D array.

```julia
using CUDA

function divide0!(y, a, b)
    for j = 1:size(y, 2)
        for i = 1:size(y, 1)
            @inbounds y[i, j] = a[i, j] / b[i]
        end
    end

    return nothing
end

function divide1!(y, a, b)
    idx = threadIdx().x
    idy = threadIdx().y
    strx = blockDim().x
    stry = blockDim().y
    for j = idy:stry:size(y, 2)
        for i = idx:strx:size(y, 1)
            @inbounds y[i, j] = a[i, j] / b[i]
        end
    end

    return nothing
end

function divide2!(y, a, b)
    idx = (blockIdx().x - 1) * blockDim().x + threadIdx().x
    idy = (blockIdx().y - 1) * blockDim().y + threadIdx().y
    for j = idy
        for i = idx
            @inbounds y[i, j] = a[i, j] / b[i]
        end
    end

    return nothing
end

a = rand(32, 16) |> CuArray
b = rand(32) |> CuArray

y0 = zero(a)
y1 = zero(a)
y2 = zero(a)

@cuda divide0!(y0, a, b)
@cuda threads=32 divide1!(y1, a, b)
@cuda threads=32 blocks=16 divide2!(y2, a, b)

```

However, I found `divide2` doesn’t give a same result as `0` and `1`.

```julia
julia> y0 == y1
true

julia> y1 == y2
false

```

Do I make any silly mistakes here?

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [July 17, 2021, 11:47pm UTC](https://discourse.julialang.org/t/indexing-2d-cuarray/64825/2 "2021-07-17T23:47:15Z")

</div>

> [@vavrines](#):
>
> ```julia
> idx = (blockIdx().x - 1) * blockDim().x + threadIdx().x
> idy = (blockIdx().y - 1) * blockDim().y + threadIdx().y
> 
> ```

neither is a range. you could’ve figured it out by printing `idx` and `idy`.

---

<div class="post-metadata">

**Author:** ![fedoroff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fedoroff/32/53209_2.png) [@fedoroff](https://discourse.julialang.org/u/fedoroff)\
**Post date:** [July 18, 2021, 6:37am UTC](https://discourse.julialang.org/t/indexing-2d-cuarray/64825/3 "2021-07-18T06:37:25Z")

</div>

With `CartesianIndices` you can iterate using the linear index and at the same time have access to the indices along each dimension:

```julia
function divide2!(y, a, b)
    id = (blockIdx().x - 1) * blockDim().x + threadIdx().x
    stride = blockDim().x * gridDim().x

    Nx, Ny = size(y)

    cind = CartesianIndices((Nx, Ny))

    for k=id:stride:Nx*Ny
        i = cind[k][1]
        j = cind[k][2]
        @inbounds y[i, j] = a[i, j] / b[i]
    end

    return nothing
end

```

---

<div class="post-metadata">

**Author:** ![vavrines](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vavrines/32/8024_2.png) [@vavrines](https://discourse.julialang.org/u/vavrines)\
**Post date:** [July 18, 2021, 8:27am UTC](https://discourse.julialang.org/t/indexing-2d-cuarray/64825/4 "2021-07-18T08:27:38Z")

</div>

Following the above codes, this way also works.

```julia
function divide2!(y, a, b)
    idx = (blockIdx().x - 1) * blockDim().x + threadIdx().x
    idy = (blockIdx().y - 1) * blockDim().y + threadIdx().y
    strx = blockDim().x * gridDim().x
    stry = blockDim().y * gridDim().y
    Nx, Ny = size(y)

    for j = idy:stry:Ny
        for i = idx:strx:Nx
            @inbounds y[i, j] = a[i, j] / b[i]
        end
    end

    return nothing
end

```

Note it here for reference.
