Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions src/pocl/compiler/execution.jl
Original file line number Diff line number Diff line change
Expand Up @@ -204,26 +204,29 @@ function clfunction(f::F, tt::TT = Tuple{}; kwargs...) where {F, TT}
# Resolve the cl.Kernel for the active context. Linear scan over the
# session-local cache; almost always n=1, so this is one `===` compare.
ctx = context()
kernel = Ref{nanoOpenCL.Kernel}()
cached = nothing
@inbounds for (cached_ctx, cached_kernel) in res.kernels
if cached_ctx === ctx
kernel[] = cached_kernel
cached = cached_kernel
break
end
end
if !isassigned(kernel)
kernel[] = link_kernel(job, res.obj::Vector{UInt8}, res.entry::String)
kernel = if cached === nothing
linked = link_kernel(job, res.obj::Vector{UInt8}, res.entry::String)
# Don't cache session-local kernel handles while precompiling: the
# results struct is serialized into the package image along with its
# CodeInstance, and the handles would come back dangling.
if ccall(:jl_generating_output, Cint, ()) != 1
push!(res.kernels, (ctx, kernel[]))
push!(res.kernels, (ctx, linked))
end
linked
else
cached
end

h = hash(kernel[], hash(f, hash(tt)))
h = hash(kernel, hash(f, hash(tt)))
return get!(_kernel_instances, h) do
HostKernel{F, tt}(f, kernel[], res.device_rng)
HostKernel{F, tt}(f, kernel, res.device_rng)
end::HostKernel{F, tt}
end
end
Expand All @@ -237,11 +240,16 @@ end
# Julia's code cache, so the post-compile `cached_results` re-fetch is guaranteed to
# succeed. The `compile_hook` check additionally forces the compile path so
# reflection-style consumers (`@device_code_*`) observe the compilation even on a hit.
function compile_or_lookup(@nospecialize(job::CompilerJob))::OpenCLResults
# Keep this specialized so the caller can avoid boxing `CompilerJob`. Its type parameters
# only identify the target and compiler parameters, so this is bounded per back-end rather
# than specialized for every kernel; `@noinline` keeps the body out of each `clfunction`.
@noinline function compile_or_lookup(job::CompilerJob)::OpenCLResults
res = GPUCompiler.cached_results(OpenCLResults, job)
if res === nothing || res.obj === nothing || GPUCompiler.compile_hook[] !== nothing
compiled = compile_to_obj(job)
res = @something res GPUCompiler.cached_results(OpenCLResults, job)
if res === nothing
res = GPUCompiler.cached_results(OpenCLResults, job)::OpenCLResults
end
res.obj = compiled.obj
res.entry = compiled.entry
res.device_rng = compiled.device_rng
Expand Down
8 changes: 4 additions & 4 deletions src/pocl/nanoOpenCL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1293,11 +1293,11 @@ function set_arg!(k::Kernel, idx::Integer, arg::T) where {T}
return k
end

set_args!(k::Kernel, args::Vararg{Any, N}) where {N} = set_args!(k, 1, args...)
@inline set_args!(k::Kernel, i::Int) = nothing
@inline function set_args!(k::Kernel, i::Int, arg, args::Vararg{Any, N}) where {N}
set_args!(k::Kernel, args::Vararg{Any, N}) where {N} = _set_args!(k, 1, args...)
@inline _set_args!(k::Kernel, i::Int) = nothing
@inline function _set_args!(k::Kernel, i::Int, arg, args::Vararg{Any, N}) where {N}
set_arg!(k, i, arg)
return set_args!(k, i + 1, args...)
return _set_args!(k, i + 1, args...)
end

# work sizes padded to the three dimensions OpenCL devices support
Expand Down
Loading