GPUArrays.jl icon indicating copy to clipboard operation
GPUArrays.jl copied to clipboard

Broadcast of function with errors results in CPU execution

Open maleadt opened this issue 7 years ago • 0 comments

This is a fun one, not sure about the solution but it hurts usability. Take the following MWE:

using CuArrays
import CUDAnative

using ForwardDiff

@inline function CUDAnative.erf(input::ForwardDiff.Dual{T}) where T
    x = ForwardDiff.value(input)
    val = CUDAnative.erf(x)
    deriv = CUDAnative.sqrt(π)
    return deriv
end

a = CuArray{Float32}(1:1)
CUDAnative.erf.(a) # works

b = CuArray(ForwardDiff.Dual.(1f0:1f0, 1f0))
CUDAnative.erf.(b) # crashes

This crashes with FATAL ERROR: Symbol "__nv_erff"not found, indicating CPU execution of the GPU kernel. As it turns out, CUDAnative.erf(input::ForwardDiff.Dual{T}) contains an error: CUDAnative.erf is not defined for Irrational, meaning the call to CUDAnative.sqrt(π) (and the entire method) infers to Bottom. As a result, Broadcast.combine_eltypes works with Union{}, which isn't a concrete type, calling the fallback broadcast operation that uses scalar indexing.

I'm not sure whether we should just classify this under "user error" and move along, or try to catch this. For some reason, it doesn't seem caught by allowscalar(false) either:

julia> b[1]
ERROR: scalar getindex is disabled
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] assertscalar at /home/tbesard/Julia/GPUArrays/src/indexing.jl:6 [inlined]
 [3] getindex(::CuArray{ForwardDiff.Dual{Nothing,Float32,1},1}, ::Int64) at /home/tbesard/Julia/GPUArrays/src/indexing.jl:29
 [4] top-level scope at none:0

julia> CUDAnative.erf.(b)
FATAL ERROR: Symbol "__nv_erff"not found

maleadt avatar Aug 22 '18 10:08 maleadt