# A reverse! for CuArrays and Nd arrays

**URL:** <https://discourse.julialang.org/t/a-reverse-for-cuarrays-and-nd-arrays/24731>\
**Category:** Performance\
**Tags:** cuda\
**Created:** [May 29, 2019, 12:32pm UTC](https://discourse.julialang.org/t/a-reverse-for-cuarrays-and-nd-arrays/24731 "2019-05-29T12:32:30Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![rveltz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rveltz/32/2707_2.png) [@rveltz](https://discourse.julialang.org/u/rveltz)\
**Post date:** [May 29, 2019, 12:32pm UTC](https://discourse.julialang.org/t/a-reverse-for-cuarrays-and-nd-arrays/24731/1 "2019-05-29T12:32:30Z")

</div>

Dear All,

I have a 3d array `V = zeros(N,N,N)` and I would like to reverse it with respect to the last component. I achieve this by using the following function. This works well using `CuArray` (on master, see [link](https://github.com/JuliaGPU/CuArrays.jl/issues/299)) for `A` but this is very inefficient as `N~100`. Hence the gpu is wasted doing such a small reverse.

I am wondering if any of you has an idea to speed this up on GPU?

Thank you very much

Best regards

```julia
function myreverse!(A) 
	n = size(A)
	for jj = 1:n[2], ii = 1:n[1] 
		reverse!(A[ii,jj,:])
	end
end

```

---

<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:** [May 29, 2019, 10:10pm UTC](https://discourse.julialang.org/t/a-reverse-for-cuarrays-and-nd-arrays/24731/2 "2019-05-29T22:10:35Z")

</div>

Are you sure this works? I think you may need `view(A, ii,jj,:)` in there.

I see that my wish for a 1D reverse was granted, but really one should write version which takes `dims=3` too I guess.

---

<div class="post-metadata">

**Author:** ![rveltz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rveltz/32/2707_2.png) [@rveltz](https://discourse.julialang.org/u/rveltz)\
**Post date:** [May 29, 2019, 10:26pm UTC](https://discourse.julialang.org/t/a-reverse-for-cuarrays-and-nd-arrays/24731/3 "2019-05-29T22:26:14Z")

</div>

Yes with `CuArrays#master`

---

<div class="post-metadata">

**Author:** ![rveltz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rveltz/32/2707_2.png) [@rveltz](https://discourse.julialang.org/u/rveltz)\
**Post date:** [June 18, 2019, 12:58pm UTC](https://discourse.julialang.org/t/a-reverse-for-cuarrays-and-nd-arrays/24731/4 "2019-06-18T12:58:55Z")

</div>

In search for a quick fix waiting for the correct implementation, I tried

```julia
A0 = rand(10,10,10)
A = copy(A0)
myreverse!(A)
A2 = A[:,:,10:-1:1]
norm(A-A2)

```

but to my surprise, it does not give the same result…

---

<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:** [June 18, 2019, 3:09pm UTC](https://discourse.julialang.org/t/a-reverse-for-cuarrays-and-nd-arrays/24731/5 "2019-06-18T15:09:20Z")

</div>

It remains my opinion that `myreverse!` does nothing, because `A[...]` makes a copy, without touching `A`.

But indexing with a range does seem to work on CuArrays, so this is a plausible way to go. I haven’t timed it to see if it’s quick:

```julia
A = collect(reshape(1:27, 3,3,3))
A0 = copy(A)

myreverse!(A)
A
A == A0

A[:,:,3:-1:1]
view(A, :,:,3:-1:1) # or view(A, :, :, reverse(axes(A,3)) )

using CuArrays
cA = cu(A)

CuArrays.allowscalar(false)
cA[:,:,3:-1:1]
view(cA, :,:,3:-1:1)
cA .= view(cA, :,:,3:-1:1)

```

---

<div class="post-metadata">

**Author:** ![rveltz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rveltz/32/2707_2.png) [@rveltz](https://discourse.julialang.org/u/rveltz)\
**Post date:** [June 18, 2019, 3:23pm UTC](https://discourse.julialang.org/t/a-reverse-for-cuarrays-and-nd-arrays/24731/6 "2019-06-18T15:23:48Z")

</div>

You were right… Thank you

```julia
function myreverse!(A) 
               n = size(A)
               for jj = 1:n[2], ii = 1:n[1] 
                       reverse!(view(A,ii,jj,:))
               end
       end

```

---

<div class="post-metadata">

**Author:** ![rveltz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rveltz/32/2707_2.png) [@rveltz](https://discourse.julialang.org/u/rveltz)\
**Post date:** [July 8, 2019, 9:06am UTC](https://discourse.julialang.org/t/a-reverse-for-cuarrays-and-nd-arrays/24731/7 "2019-07-08T09:06:12Z")

</div>

For those who are interested, I use the following which does the trick

```julia
function myreverse!(A::AbstractArray)
		n = size(A)
		A .= A[:,:,n[3]:-1:1]
	end

```
