88const OpenCLCompilerConfig = CompilerConfig{SPIRVCompilerTarget, OpenCLCompilerParams}
99const OpenCLCompilerJob = CompilerJob{SPIRVCompilerTarget, OpenCLCompilerParams}
1010
11+ """
12+ OpenCLResults
13+
14+ Cached compilation results for an OpenCL kernel job, managed by
15+ `GPUCompiler.cached_results`. Fields are populated through the compile pipeline:
16+ `obj` (SPIR-V bytes) + `entry` + `device_rng` after codegen, and `kernels` after the
17+ session-local link onto an OpenCL context. The first three are session-portable
18+ (cached through precompilation, except when GPUCompiler marks the job
19+ session-dependent and wipes its entries before image serialization); `kernels` is
20+ session-local and never populated during precompilation. `obj === nothing`
21+ identifies a job that has not been compiled yet.
22+
23+ `kernels` is a small linear cache of `(cl.Context, cl.Kernel)` pairs. The cache partition
24+ already covers everything that affects codegen via `GPUCompiler.cache_owner`, so the only
25+ runtime-visible dimension left is the OpenCL context that owns the linked `cl.Kernel`.
26+ A linear scan with `===` is fastest in the common case (n=1) and stays cheap for the
27+ rare workload that bounces between a handful of contexts on the same device.
28+ """
29+ mutable struct OpenCLResults
30+ obj:: Union{Nothing, Vector{UInt8}} # SPIR-V binary
31+ entry:: Union{Nothing, String}
32+ device_rng:: Bool
33+ kernels:: Vector{Tuple{cl.Context, cl.Kernel}} # session-local; linear-scanned
34+ OpenCLResults () = new (nothing , nothing , false , Tuple{cl. Context, cl. Kernel}[])
35+ end
36+
1137GPUCompiler. runtime_module (:: CompilerJob{<:Any, OpenCLCompilerParams} ) = POCL
1238
1339GPUCompiler. method_table_view (job:: OpenCLCompilerJob ) = GPUCompiler. StackedMethodTable (job. world, method_table, SPIRVIntrinsics. method_table)
@@ -114,18 +140,7 @@ function GPUCompiler.finish_linked_module!(@nospecialize(job::OpenCLCompilerJob)
114140end
115141
116142
117- # # compiler implementation (cache, configure, compile, and link)
118-
119- # cache of compilation caches, per context
120- const _compiler_caches = Dict {cl.Context, Dict{Any, Any}} ()
121- function compiler_cache (ctx:: cl.Context )
122- cache = get (_compiler_caches, ctx, nothing )
123- if cache === nothing
124- cache = Dict {Any, Any} ()
125- _compiler_caches[ctx] = cache
126- end
127- return cache
128- end
143+ # # compiler implementation (configure, compile, and link)
129144
130145# cache of compiler configurations, per device (but additionally configurable via kwargs)
131146const _toolchain = Ref {Any} ()
@@ -153,10 +168,13 @@ end
153168 return CompilerConfig (target, params; kernel, name, always_inline)
154169end
155170
156- # compile to executable machine code
157- function compile (@nospecialize (job:: CompilerJob ))
158- # TODO : this creates a context; cache those.
159- return obj, meta = JuliaContext () do ctx
171+ # run inference + LLVM codegen + SPIR-V emission. returns `(obj, entry, device_rng)`,
172+ # all session-portable so they survive precompilation when stored on a cached `CodeInstance`.
173+ const compilations = Threads. Atomic {Int} (0 )
174+ function compile_to_obj (@nospecialize (job:: CompilerJob ))
175+ compilations[] += 1
176+
177+ return JuliaContext () do ctx
160178 obj, meta = GPUCompiler. compile (:obj , job)
161179
162180 entry = LLVM. name (meta. entry)
@@ -166,13 +184,13 @@ function compile(@nospecialize(job::CompilerJob))
166184 end
167185end
168186
169- # link into an executable kernel
170- function link (@nospecialize (job:: CompilerJob ), compiled )
187+ # link the SPIR-V bytes into a session-local `cl.Kernel` on the active context.
188+ function link_kernel (@nospecialize (job:: CompilerJob ), obj :: Vector{UInt8} , entry :: String )
171189 prog = if " cl_khr_il_program" in device (). extensions
172- cl. Program (compiled . obj, context ())
190+ cl. Program (obj, context ())
173191 else
174192 error (" Your device does not support SPIR-V, which is currently required for native execution." )
175193 end
176194 cl. build! (prog)
177- return (; kernel = cl. Kernel (prog, compiled . entry), compiled . device_rng )
195+ return cl. Kernel (prog, entry)
178196end
0 commit comments