# Exponents with CuArrays

**URL:** <https://discourse.julialang.org/t/exponents-with-cuarrays/22218>\
**Category:** GPU\
**Created:** [March 22, 2019, 9:44pm UTC](https://discourse.julialang.org/t/exponents-with-cuarrays/22218 "2019-03-22T21:44:04Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![bryce](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bryce/32/15193_2.png) [@bryce](https://discourse.julialang.org/u/bryce)\
**Post date:** [March 22, 2019, 9:44pm UTC](https://discourse.julialang.org/t/exponents-with-cuarrays/22218/1 "2019-03-22T21:44:05Z")

</div>

I’m trying out what I thought were some basic array operations with CuArrays, and have discovered that I can’t do exponents (a.^b) with CuArrays. Here’s a minimal example:

```julia
julia> m = CuArrays.cu([1])
1-element CuArrays.CuArray{Float32,1}:
 1.0

julia> m .+ m
1-element CuArrays.CuArray{Float32,1}:
 2.0

julia> m .* m
1-element CuArrays.CuArray{Float32,1}:
 1.0

julia> m .^ m
ERROR: InvalidIRError: compiling #23(CuArrays.CuKernelState, CUDAnative.CuDeviceArray{Float32,1,CUDAnative.AS.Global}, Base.Broadcast.Broadcasted{Nothing,Tuple{Base.OneTo{Int64}},typeof(^),Tuple{Base.Broadcast.Extruded{CUDAnative.CuDeviceArray{Float32,1,CUDAnative.AS.Global},Tuple{Bool},Tuple{Int64}},Base.Broadcast.Extruded{CUDAnative.CuDeviceArray{Float32,1,CUDAnative.AS.Global},Tuple{Bool},Tuple{Int64}}}}) resulted in invalid LLVM IR
Reason: unsupported call through a literal pointer (call to jl_alloc_string)

```

Can anyone help me understand and work around this error? What I’m actually trying to do is more like the following.

```julia
julia> m = [.4 .6]
1×2 Array{Float64,2}:
 0.4 0.6

julia> p = [3 0; 2 1; 1 2; 0 3]
4×2 Array{Int64,2}:
 3 0
 2 1
 1 2
 0 3

julia> d = [1; 3; 3; 1]
4-element Array{Int64,1}:
 1
 3
 3
 1

julia> prod(m.^p, dims=2).*d
4×1 Array{Float64,2}:
 0.064
 0.288
 0.432
 0.216

```

---

<div class="post-metadata">

**Author:** ![maleadt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maleadt/32/10097_2.png) [@maleadt](https://discourse.julialang.org/u/maleadt)\
**Post date:** [March 23, 2019, 7:54am UTC](https://discourse.julialang.org/t/exponents-with-cuarrays/22218/2 "2019-03-23T07:54:09Z")

</div>

Oh interesting, I hadn’t seen that error before: looks like it comes from the string failure message that is constructed in the case of a domain error. I’ve filed an issue: [throw\_... messages: invalid call to `jl_alloc_string` · Issue #54 · JuliaGPU/CUDA.jl · GitHub](https://github.com/JuliaGPU/CUDAnative.jl/issues/367)

Note that exponentation by a floating point number is problematic anyhow due to an LLVM issue: [Cannot select `fpow` while lowering `pow.f32` · Issue #71 · JuliaGPU/CUDA.jl · GitHub](https://github.com/JuliaGPU/CUDAnative.jl/issues/113)

Constant integer exponentation works though:

```julia
julia> m = CuArrays.cu([2])
1-element CuArray{Float32,1}:
 2.0

julia> m .^ 2
1-element CuArray{Float32,1}:
 4.0

```

---

<div class="post-metadata">

**Author:** ![maleadt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maleadt/32/10097_2.png) [@maleadt](https://discourse.julialang.org/u/maleadt)\
**Post date:** [March 23, 2019, 8:00am UTC](https://discourse.julialang.org/t/exponents-with-cuarrays/22218/3 "2019-03-23T08:00:55Z")

</div>

For a workaround, which currently still applies to many Base mathematical operations: have a look at CUDAnative and whether it provides a GPU compatible alternative. In the case of exponentation, that’s `CUDAnative.pow`:

```julia
help?> CUDAnative.pow
  No documentation found.

  CUDAnative.pow is a Function.

  # 4 methods for generic function "pow":
  [1] pow(x::Float32, y::Int32) in CUDAnative at /home/tbesard/Julia/CUDAnative/src/device/cuda/libdevice.jl:197
  [2] pow(x::Float64, y::Int32) in CUDAnative at /home/tbesard/Julia/CUDAnative/src/device/cuda/libdevice.jl:196
  [3] pow(x::Float32, y::Float32) in CUDAnative at /home/tbesard/Julia/CUDAnative/src/device/cuda/libdevice.jl:194
  [4] pow(x::Float64, y::Float64) in CUDAnative at /home/tbesard/Julia/CUDAnative/src/device/cuda/libdevice.jl:193

julia> m = CuArrays.cu([2])
1-element CuArray{Float32,1}:
 2.0

julia> CUDAnative.pow.(m, m)
1-element CuArray{Float32,1}:
 4.0

```

In the future, once we get Cassette working properly, we’ll be dispatching to these compatible methods automatically.
