Skip to content

Commit 0c08fd0

Browse files
maleadtclaude
andauthored
Restore current_job across nested compilation. (#855)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent ad1dbfd commit 0c08fd0

3 files changed

Lines changed: 58 additions & 27 deletions

File tree

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "GPUCompiler"
22
uuid = "61eb1bfa-7361-4325-ad38-22787b887f55"
3-
version = "1.22.3"
3+
version = "1.22.4"
44
authors = ["Tim Besard <tim.besard@gmail.com>"]
55

66
[workspace]

src/driver.jl

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -82,44 +82,53 @@ function compile_unhooked(output::Symbol, @nospecialize(job::CompilerJob); kwarg
8282
error("No active LLVM context. Use `JuliaContext()` do-block syntax to create one.")
8383
end
8484

85-
@tracepoint "Validation" begin
86-
check_method(job) # not optional
87-
job.config.validate && check_invocation(job)
88-
end
85+
# save/restore the `current_job` global that passes read: compilation nests (the relink
86+
# pass rebuilds the runtime via `compile_unhooked` on a cold cache), and a leaked inner
87+
# `kernel=false` job would make the outer kernel-state passes misfire.
88+
global current_job
89+
prev_job = @isdefined(current_job) ? current_job : nothing
90+
try
91+
@tracepoint "Validation" begin
92+
check_method(job) # not optional
93+
job.config.validate && check_invocation(job)
94+
end
8995

90-
prepare_job!(job)
96+
prepare_job!(job)
9197

9298

93-
## LLVM IR
99+
## LLVM IR
94100

95-
ir, ir_meta = emit_llvm(job)
101+
ir, ir_meta = emit_llvm(job)
96102

97-
if output == :llvm
98-
if job.config.strip
99-
@tracepoint "strip debug info" strip_debuginfo!(ir)
100-
end
103+
if output == :llvm
104+
if job.config.strip
105+
@tracepoint "strip debug info" strip_debuginfo!(ir)
106+
end
101107

102-
return ir, ir_meta
103-
end
108+
return ir, ir_meta
109+
end
104110

105111

106-
## machine code
112+
## machine code
107113

108-
format = if output == :asm
109-
LLVM.API.LLVMAssemblyFile
110-
elseif output == :obj
111-
LLVM.API.LLVMObjectFile
112-
else
113-
error("Unknown assembly format $output")
114-
end
115-
asm, asm_meta = emit_asm(job, ir, format)
114+
format = if output == :asm
115+
LLVM.API.LLVMAssemblyFile
116+
elseif output == :obj
117+
LLVM.API.LLVMObjectFile
118+
else
119+
error("Unknown assembly format $output")
120+
end
121+
asm, asm_meta = emit_asm(job, ir, format)
116122

117-
if output == :asm || output == :obj
118-
return asm, (; asm_meta..., ir_meta..., ir)
119-
end
123+
if output == :asm || output == :obj
124+
return asm, (; asm_meta..., ir_meta..., ir)
125+
end
120126

121127

122-
error("Unknown compilation output $output")
128+
error("Unknown compilation output $output")
129+
finally
130+
current_job = prev_job
131+
end
123132
end
124133

125134
# primitive mechanism for deferred compilation, for implementing CUDA dynamic parallelism.

test/ptx.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,28 @@
1010
end
1111
end
1212

13+
@testset "kernel state survives a runtime rebuild during optimization" begin
14+
# Clearing the cache forces the relink pass inside `optimize!` to rebuild the runtime
15+
# (nested compilation); the kernel must still get its state argument afterwards.
16+
mod = @eval module $(gensym())
17+
function kernel(x)
18+
x < 1 && throw(DivideError())
19+
return
20+
end
21+
end
22+
old_cache = GPUCompiler.compile_cache
23+
ir = try
24+
GPUCompiler.compile_cache = nothing
25+
sprint() do io
26+
PTX.code_llvm(io, mod.kernel, Tuple{Int}; kernel=true, dump_module=true)
27+
end
28+
finally
29+
GPUCompiler.compile_cache = old_cache
30+
end
31+
@test occursin("gpu_report_exception", ir)
32+
@test occursin("[1 x i64] %state", ir)
33+
end
34+
1335
@testset "kernel functions" begin
1436
@testset "kernel argument attributes" begin
1537
mod = @eval module $(gensym())

0 commit comments

Comments
 (0)