I’m having trouble computing an AD gradient of the gamma PDF using a gpu array. The goal is to use this as part of a Flux project. I am happy to open an issue, but I am new enough to gpu coding that I want to make sure I am not doing something silly.
Here is an MWE:
using Revise, Flux, CuArrays, BenchmarkTools, CUDAnative, CUDAapi
CuArrays.allowscalar(false)
function vecgammalogpdf(k::TV, θ::TV, x::TV)::TV where TV<:CuArrays.CuVector
Γs = -(CUDAnative.lgamma).(k) .- k .* log.(θ) .+ (k .- 1f0) .* log.(x) .- x ./ θ
return Γs
end
function testvecgammalogpdf(N)
τ = abs.(randn(Float32, N)) .+ .001f0
absμ = abs.(randn(Float32, N)) .+ .001f0
θ = 1.0f0 ./ τ
k = absμ .* τ
v = rand(Float32, N)
cuθ = θ |> gpu
cuk = k |> gpu
cuv = v |> gpu
@info "Make sure the function works:"
println(sum(vecgammalogpdf(cuk, cuθ, cuv)))
@info "compute the gradient"
gs = gradient(()->sum(vecgammalogpdf(cuk, cuθ, cuv)), Flux.params(cuk, cuθ, cuv))
println(gs)
end
N= 10^5
sleep(0.5)
testvecgammalogpdf(N)
When I run this, I get:
[ Info: Make sure the function works:
-134438.14
[ Info: compute the gradient
ERROR: LoadError: scalar getindex is disallowed
Stacktrace:
[1] error(::String) at .\error.jl:33
[2] assertscalar(::String) at C:\Users\Clinton\.julia\packages\GPUArrays\QDGmr\src\host\indexing.jl:41
[3] getindex(::CuArray{Float32,1,Nothing}, ::Int64) at C:\Users\Clinton\.julia\packages\GPUArrays\QDGmr\src\host\indexing.jl:86
[4] _broadcast_getindex at .\broadcast.jl:597 [inlined]
[5] _getindex at .\broadcast.jl:628 [inlined]
[6] _broadcast_getindex at .\broadcast.jl:603 [inlined]
[7] getindex at .\broadcast.jl:564 [inlined]
[8] copy at .\broadcast.jl:854 [inlined]
[9] materialize at .\broadcast.jl:820 [inlined]
[10] broadcast_forward at C:\Users\Clinton\.julia\packages\Zygote\wkc82\src\lib\broadcast.jl:173 [inlined]
[11] adjoint at C:\Users\Clinton\.julia\packages\Zygote\wkc82\src\lib\broadcast.jl:189 [inlined]
[12] _pullback at C:\Users\Clinton\.julia\packages\ZygoteRules\6nssF\src\adjoint.jl:47 [inlined]
[13] adjoint at C:\Users\Clinton\.julia\packages\Zygote\wkc82\src\lib\lib.jl:167 [inlined]
[14] _pullback at C:\Users\Clinton\.julia\packages\ZygoteRules\6nssF\src\adjoint.jl:47 [inlined]
[15] broadcasted at .\broadcast.jl:1232 [inlined]
[16] vecgammalogpdf at C:\Users\Clinton\Dropbox\Projects\Capacity\mwe.jl:693 [inlined]
[17] _pullback(::Zygote.Context, ::typeof(vecgammalogpdf), ::CuArray{Float32,1,Nothing}, ::CuArray{Float32,1,Nothing}, ::CuArray{Float32,1,Nothing}) at C:\Users\Clinton\.julia\packages\Zygote\wkc82\src\compiler\interface2.jl:0
[18] #62 at C:\Users\Clinton\Dropbox\Projects\Capacity\mwe.jl:716 [inlined]
[19] _pullback(::Zygote.Context, ::var"#62#63"{CuArray{Float32,1,Nothing},CuArray{Float32,1,Nothing},CuArray{Float32,1,Nothing}}) at C:\Users\Clinton\.julia\packages\Zygote\wkc82\src\compiler\interface2.jl:0
[20] pullback(::Function, ::Zygote.Params) at C:\Users\Clinton\.julia\packages\Zygote\wkc82\src\compiler\interface.jl:103
[21] gradient(::Function, ::Zygote.Params) at C:\Users\Clinton\.julia\packages\Zygote\wkc82\src\compiler\interface.jl:44
[22] testvecgammalogpdf(::Int64; tol::Float64) at C:\Users\Clinton\Dropbox\Projects\Capacity\mwe.jl:716
[23] testvecgammalogpdf(::Int64) at C:\Users\Clinton\Dropbox\Projects\Capacity\mwe.jl:701
[24] top-level scope at C:\Users\Clinton\Dropbox\Projects\Capacity\mwe.jl:722
in expression starting at C:\Users\Clinton\Dropbox\Projects\Capacity\mwe.jl:722
Without the call to CUDAnative.lgamma
everything works swimmingly, so its just that call that seems to mess things up. Also, even if I allowscalar, I get MethodError: no method matching lgamma(::ForwardDiff.Dual{Nothing,Float32,1})
.
Any help getting this to work would be appreciated!