JuliaGPU / JuliaGPU/KernelAbstractions.jl

Inconsistent `KernelError` on the GPU telling me to use `return` in my kernel

Open
#248 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Julia
Stars
523
Forks
88
Avg merge
1d 11h
Merged PRs (30d)
25

Description

Was trying to debug an issue with the use of `^` and `pow` inside `@kernel`s when I came across this weird (and incorrect/inconsistent) warning.

```julia
using KernelAbstractions
using CUDAKernels
using CUDA

@kernel function apply_f_kernel!(A, B, f)
I = @index(Global)
@inbounds A[I] = f(B[I])
end

N = 3

square(x) = x^2

for f in [sin, cos, square]
A = zeros(N)
B = zeros(N)

@info "Calling apply_f_kernel! on the CPU with f=$f..."
event = apply_f_kernel!(CPU(), N)(A, B, f, ndrange=N)
wait(event)

A = zeros(N) |> CuArray
B = zeros(N) |> CuArray

@info "Calling apply_f_kernel! on the GPU with f=$f..."
event = apply_f_kernel!(CUDADevice(), N)(A, B, ndrange=N)
wait(event)
end
```

produces

```
[ Info: Calling apply_f_kernel! on the CPU with f=sin...
[ Info: Calling apply_f_kernel! on the GPU with f=sin...
ERROR: LoadError: GPU compilation of kernel gpu_apply_f_kernel!(Cassette.Context{nametype(CUDACtx), KernelAbstractions.CompilerMetadata{KernelAbstractions.NDIteration.DynamicSize, KernelAbstractions.NDIteration.DynamicCheck, Nothing, CartesianIndices{1, Tuple{Base.OneTo{Int64}}}, KernelAbstractions.NDIteration.NDRange{1, KernelAbstractions.NDIteration.DynamicSize, KernelAbstractions.NDIteration.StaticSize{(3,)}, CartesianIndices{1, Tuple{Base.OneTo{Int64}}}, Nothing}}, Nothing, KernelAbstractions.var"##PassType#257", Nothing, Cassette.DisableHooks}, typeof(gpu_apply_f_kernel!), CuDeviceVector{Float64, 1}, CuDeviceVector{Float64, 1}) failed
KernelError: kernel returns a value of type `Union{}`

Make sure your kernel function ends in `return`, `return nothing` or `nothing`.
If the returned value is of type `Union{}`, your Julia code probably throws an exception.
Inspect the code with `@device_code_warntype` for more details.

Stacktrace:
[1] check_method(job::GPUCompiler.CompilerJob)
@ GPUCompiler ~/.julia/packages/GPUCompiler/eJOtJ/src/validation.jl:21
[2] macro expansion
@ ~/.julia/packages/TimerOutputs/4QAIk/src/TimerOutput.jl:206 [inlined]
[3] macro expansion
@ ~/.julia/packages/GPUCompiler/eJOtJ/src/driver.jl:88 [inlined]
[4] emit_julia(job::GPUCompiler.CompilerJob)
@ GPUCompiler ~/.julia/packages/GPUCompiler/eJOtJ/src/utils.jl:62
[5] cufunction_compile(job::GPUCompiler.CompilerJob)
@ CUDA ~/.julia/packages/CUDA/LTbUr/src/compiler/execution.jl:299
[6] check_cache
@ ~/.julia/packages/GPUCompiler/eJOtJ/src/cache.jl:47 [inlined]
[7] cached_compilation
@ ~/.julia/packages/Cassette/FwMN0/src/overdub.jl:582 [inlined]
[8] cufunction(f::typeof(Cassette.overdub), tt::Type{Tuple{Cassette.Context{nametype(CUDACtx), KernelAbstractions.CompilerMetadata{KernelAbstractions.NDIteration.DynamicSize, KernelAbstractions.NDIteration.DynamicCheck, Nothing, CartesianIndices{1, Tuple{Base.OneTo{Int64}}}, KernelAbstractions.NDIteration.NDRange{1, KernelAbstractions.NDIteration.DynamicSize, KernelAbstractions.NDIteration.StaticSize{(3,)}, CartesianIndices{1, Tuple{Base.OneTo{Int64}}}, Nothing}}, Nothing, KernelAbstractions.var"##PassType#257", Nothing, Cassette.DisableHooks}, typeof(gpu_apply_f_kernel!), CuDeviceVector{Float64, 1}, CuDeviceVector{Float64, 1}}}; name::String, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ CUDA ~/.julia/packages/CUDA/LTbUr/src/compiler/execution.jl:289
[9] macro expansion
@ ~/.julia/packages/CUDA/LTbUr/src/compiler/execution.jl:102 [inlined]
[10] (::KernelAbstractions.Kernel{CUDADevice, KernelAbstractions.NDIteration.StaticSize{(3,)}, KernelAbstractions.NDIteration.DynamicSize, typeof(gpu_apply_f_kernel!)})(::CuArray{Float64, 1}, ::Vararg{CuArray{Float64, 1}, N} where N; ndrange::Int64, dependencies::CUDAKernels.CudaEvent, workgroupsize::Nothing, progress::Function)
@ CUDAKernels ~/.julia/packages/CUDAKernels/cz35Z/src/CUDAKernels.jl:194
[11] top-level scope
@ ~/Oceananigans.jl/apply_f_error.jl:26
[12] include(fname::String)
@ Base.MainInclude ./client.jl:444
[13] top-level scope
@ REPL[14]:1
[14] top-level scope
@ ~/.julia/packages/CUDA/LTbUr/src/initialization.jl:81
in expression starting at /home/alir/Oceananigans.jl/apply_f_error.jl:14
```

which tells me to use `return` in the kernel but KernelAbstractions.jl doesn't allow that.

# Environment

```
julia> versioninfo()
Julia Version 1.6.1
Commit 6aaedecc44 (2021-04-23 05:59 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Xeon(R) Silver 4214 CPU @ 2.20GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-11.0.1 (ORCJIT, cascadelake)
```

Manifest

```
(Oceananigans) pkg> status -m
Project Oceananigans v0.57.1
Status `~/Oceananigans.jl/Manifest.toml`
[621f4979] AbstractFFTs v1.0.1
[79e6a3ab] Adapt v3.3.0
[4fba245c] ArrayInterface v3.1.11
[ab4f0b2a] BFloat16s v0.1.0
[fa961155] CEnum v0.4.1
[179af706] CFTime v0.1.1
[052768ef] CUDA v3.2.0
[72cfdca4] CUDAKernels v0.2.0
[7057c7e9] Cassette v0.3.6
[d360d2e6] ChainRulesCore v0.9.42
[34da2185] Compat v3.28.0
[a8cc5b0e] Crayons v4.0.4
[7445602f] CubedSphere v0.1.0
[9a962f9c] DataAPI v1.6.0
[864edb3b] DataStructures v0.18.9
[e2d170a0] DataValueInterfaces v1.0.0
[b552c78f] DiffRules v1.0.2
[ffbed154] DocStringExtensions v0.8.4
[b305315f] Elliptic v1.0.1
[e2ba6199] ExprTools v0.1.3
[7a1cc6ca] FFTW v1.4.1
[5789e2e9] FileIO v1.8.2
[0c68f7d7] GPUArrays v6.4.0
[61eb1bfa] GPUCompiler v0.11.5
[c27321d9] Glob v1.3.0
[615f187c] IfElse v0.1.0
[82899510] IteratorInterfaceExtensions v1.0.0
[033835bb] JLD2 v0.4.5
[692b3bcd] JLLWrappers v1.3.0
[0f8b85d8] JSON3 v1.8.1
[63c18a36] KernelAbstractions v0.6.2
[929cbde3] LLVM v3.7.0
[da04e1cc] MPI v0.17.2
[1914dd2f] MacroTools v0.5.6
[c03570c3] Memoize v0.4.4
[85f8d34a] NCDatasets v0.11.4
[77ba4419] NaNMath v0.3.5
[6fe1bfb0] OffsetArrays v1.8.0
[bac558e1] OrderedCollections v1.4.1
[69de0a69] Parsers v1.1.0
[0e08944d] PencilArrays v0.9.4
[4a48f351] PencilFFTs v0.12.2
[21216c6a] Preferences v1.2.2
[74087812] Random123 v1.3.1
[e6cf234a] RandomNumbers v1.4.0
[189a3867] Reexport v1.0.0
[ae029012] Requires v1.1.3
[6038ab10] Rotations v1.0.2
[1bc83da4] SafeTestsets v0.0.1
[6c6a2e73] Scratch v1.0.3
[d496a93d] SeawaterPolynomials v0.2.0
[276daf66] SpecialFunctions v1.3.0
[aedffcd0] Static v0.2.4
[90137ffa] StaticArrays v1.1.3
[15972242] StaticPermutations v0.3.0
[09ab397b] StructArrays v0.5.1
[856f2bd8] StructTypes v1.7.2
[3783bdb8] TableTraits v1.0.1
[bd369af6] Tables v1.4.2
[6aa5eb33] TaylorSeries v0.10.13
[a759f4b9] TimerOutputs v0.5.8
[3bb67fe8] TranscodingStreams v0.9.5
[bc48ee85] Tullio v0.2.14
[f5851436] FFTW_jll v3.3.9+7
[0234f1f7] HDF5_jll v1.12.0+1
[1d5cc7b8] IntelOpenMP_jll v2018.0.3+2
[856f044c] MKL_jll v2021.1.1+1
[7cb0a576] MPICH_jll v3.3.2+10
[9237b28f] MicrosoftMPI_jll v10.1.3+0
[7243133f] NetCDF_jll v400.702.400+0
[fe0851c0] OpenMPI_jll v4.0.2+2
[458c3c95] OpenSSL_jll v1.1.1+6
[efe28fd5] OpenSpecFun_jll v0.5.4+0
[0dad84c5] ArgTools
[56f22d72] Artifacts
[2a0f44e3] Base64
[ade2ca70] Dates
[8bb1440f] DelimitedFiles
[8ba89e20] Distributed
[f43a241f] Downloads
[b77e0a4c] InteractiveUtils
[4af54fe1] LazyArtifacts
[b27032c2] LibCURL
[76f85450] LibGit2
[8f399da3] Libdl
[37e2e46d] LinearAlgebra
[56ddb016] Logging
[d6f4376e] Markdown
[a63ad114] Mmap
[ca575930] NetworkOptions
[44cfe95a] Pkg
[de0858da] Printf
[3fa0cd96] REPL
[9a3f8284] Random
[ea8e919c] SHA
[9e88b42a] Serialization
[1a1011a3] SharedArrays
[6462fe0b] Sockets
[2f01184e] SparseArrays
[10745b16] Statistics
[fa267f1f] TOML
[a4e569a6] Tar
[8dfed614] Test
[cf7118a7] UUIDs
[4ec0a83e] Unicode
[e66e0078] CompilerSupportLibraries_jll
[deac9b47] LibCURL_jll
[29816b5a] LibSSH2_jll
[c8ffd9c3] MbedTLS_jll
[14a3606d] MozillaCACerts_jll
[83775a58] Zlib_jll
[8e850ede] nghttp2_jll
[3f19e933] p7zip_jll
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the reproducer in apply_f_error.jl and the @kernel apply_f_kernel! entry point, then trace the GPU compilation path through CUDAKernels.jl:194 and GPUCompiler's validation.jl:21. Done means the GPU diagnostic is consistent with KernelAbstractions kernel rules and no longer gives incorrect return guidance for this case.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.