# Rotr90 of a CUDA.CuArray

**URL:** <https://discourse.julialang.org/t/rotr90-of-a-cuda-cuarray/88308>\
**Category:** GPU\
**Created:** [October 5, 2022, 5:15pm UTC](https://discourse.julialang.org/t/rotr90-of-a-cuda-cuarray/88308 "2022-10-05T17:15:31Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![leifdenby](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leifdenby/32/43277_2.png) [@leifdenby](https://discourse.julialang.org/u/leifdenby)\
**Post date:** [October 5, 2022, 5:15pm UTC](https://discourse.julialang.org/t/rotr90-of-a-cuda-cuarray/88308/1 "2022-10-05T17:15:31Z")

</div>

I’m trying to implement a neural network which rotates the image within the layers of the network. My question is: is there a way to use something like `Base.rotr90` on a CUDA.CuArray while disabling scalar indexing (`CUDA.allowscalar(false)`)?

Here’s what I use on the CPU:

```julia
a = randn((4, 4, 3, 2))
mapslices(rotr90, a, dims=[1,2])

```

on the GPU I tried:

```julia
using CUDA

CUDA.allowscalar(false)
a = randn((4, 4, 3, 2)) |> Flux.gpu
mapslices(rotr90, a, dims=[1,2])

```

I get the following error (that scalar indexing is disabled):

```julia
ERROR: Scalar indexing is disallowed.
Invocation of getindex resulted in scalar indexing of a GPU array.
This is typically caused by calling an iterating implementation of a method.
Such implementations *do not* execute on the GPU, but very slowly on the CPU,
and therefore are only permitted from the REPL for prototyping purposes.
If you did intend to index this array, annotate the caller with @allowscalar.

```

Is there any way around this or should I just use scalar indexing?

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [October 5, 2022, 5:22pm UTC](https://discourse.julialang.org/t/rotr90-of-a-cuda-cuarray/88308/2 "2022-10-05T17:22:00Z")

</div>

you could try a matrix multiplication. it’s way less efficient, but very well might be faster.

---

<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:** [October 5, 2022, 8:21pm UTC](https://discourse.julialang.org/t/rotr90-of-a-cuda-cuarray/88308/3 "2022-10-05T20:21:29Z")

</div>

It’s just a reverse & a transpose, so you can do something like this:

```julia
julia> using JLArrays; JLArrays.allowscalar(false)

julia> b = jl(mapslices(rotr90, a, dims=(1,2)));

julia> b == permutedims(jl(a)[end:-1:begin, :, :, :], (2,1,3,4))
true

julia> b == permutedims(reverse(jl(a); dims=1), (2,1,3,4))
ERROR: Scalar indexing is disallowed. # unsure about CuArray

# that's 2 copies, lazier variants:

julia> b == @views permutedims(jl(a)[end:-1:begin, :, :, :], (2,1,3,4))
true

julia> b == PermutedDimsArray(jl(a)[end:-1:begin, :, :, :], (2,1,3,4))
true

julia> b == @views PermutedDimsArray(jl(a)[end:-1:begin, :, :, :], (2,1,3,4))  
ERROR: Scalar indexing is disallowed. # two wrappers generally doesn't work

# something else I tried:

julia> using TensorCast

julia> x = rand(1:99, 2, 3)
2×3 Matrix{Int64}:
 51 2 69
 95 17 48

julia> @cast y[i,j] := x[-j,i]
3×2 transpose(view(::Matrix{Int64}, 2:-1:1, :)) with eltype Int64:
 95 51
 17 2
 48 69

julia> y == rotr90(x)
true

julia> @cast y[i,j] := x[-j,i] lazy=false # makes a Matrix
3×2 Matrix{Int64}:
 95 51
 17 2
 48 69

julia> @cast y[i,j] := jl(x)[-j,i] lazy=false # not lazy enough!
ERROR: Scalar indexing is disallowed.

```

---

<div class="post-metadata">

**Author:** ![leifdenby](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leifdenby/32/43277_2.png) [@leifdenby](https://discourse.julialang.org/u/leifdenby)\
**Post date:** [October 6, 2022, 10:03am UTC](https://discourse.julialang.org/t/rotr90-of-a-cuda-cuarray/88308/4 "2022-10-06T10:03:40Z")

</div>

Thank you so much (both) for helping me with this!

First, excuse my ignorance but what is the `JLArrays` package? I had a short search for it, but nothing on [Julia Packages](https://juliapackages.com/packages?search=JLArrays). I tried adding `JLArrays` to my project and got version `v0.1.1` is this the one you were using @mcabbott?

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [October 6, 2022, 10:15am UTC](https://discourse.julialang.org/t/rotr90-of-a-cuda-cuarray/88308/5 "2022-10-06T10:15:44Z")

</div>

It’s on juliahub (v8.5.0), that’s what I use to look up packages, I’m not sure [juliapackages.com](http://juliapackages.com) is maintained (where did you find it? if/since confirmed no longer maintained, I think I should edit it out of the Julia wikibook).  
[JuliaHub](https://juliahub.com/ui/Packages/JLArrays/7mj26/0.1.1)

---

<div class="post-metadata">

**Author:** ![leifdenby](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leifdenby/32/43277_2.png) [@leifdenby](https://discourse.julialang.org/u/leifdenby)\
**Post date:** [October 6, 2022, 10:16am UTC](https://discourse.julialang.org/t/rotr90-of-a-cuda-cuarray/88308/6 "2022-10-06T10:16:38Z")

</div>

Ah, I see now. Reading the source of `JLArrays` after it had been installed on my computer I can see it’s a “reference implementation” of `GPUArrays` but for CPUs. `JLArrays` is for use in development, for example testing, smart! Maybe I should start using it with my CI setup. There most be some dev-notes somewhere about using JLArrays, but I haven’t come across them yet. If anyone comes across them and would like to share, please do.

So, If I replace all `jl` calls in your code with `gpu` (from the `Flux` package) and `JLArrays.allowscalar(false)` with `CUDA.allowscalar(false)` it should all work.

I’ll do a bit of benchmark testing on the ideas you sent. Thanks again!
