Repository navigation
Preserve @oneapi arguments behind a function barrier - #685
Merged
Merged
Conversation
`@oneapi` wrapped its arguments in `GC.@preserve` in the caller's code, where an argument can be a union of singleton types, e.g. the function in `for op in (max, min)`. Julia 1.12 and 1.13.0-1.13.1 emit a null operand for preserving such a value, crashing LLVM while compiling the caller (JuliaLang/julia#63482). Pass the arguments to a function instead, as CUDA.jl does, so that they have concrete types where they are preserved. Fixes #669
Contributor
|
Your PR requires formatting changes to meet the project's style guidelines. Click here to view the suggested changes.diff --git a/src/compiler/execution.jl b/src/compiler/execution.jl
index 1f240ef..1b51bbd 100644
--- a/src/compiler/execution.jl
+++ b/src/compiler/execution.jl
@@ -114,8 +114,13 @@ macro oneapi(ex...)
# FIXME: macro hygiene wrt. escaping kwarg values (this broke with 1.5)
# we esc() the whole thing now, necessitating gensyms...
push!(code.args,
- :($compile_and_launch($f, ($(var_exprs...),), $(Val(launch)),
- (; $(call_kwargs...)), (; $(compiler_kwargs...)))))
+ :(
+ $compile_and_launch(
+ $f, ($(var_exprs...),), $(Val(launch)),
+ (; $(call_kwargs...)), (; $(compiler_kwargs...))
+ )
+ )
+ )
return esc(quote
let
@@ -130,10 +135,12 @@ end
# arguments have concrete types when they are preserved: `GC.@preserve` of a value that is a
# union of singletons, e.g. `op` in `for op in (max, min)`, crashes codegen on Julia 1.12 and
# 1.13.0-1.13.1 (JuliaLang/julia#63482).
-@inline function compile_and_launch(f::F, args::Tuple, ::Val{launch},
- call_kwargs::NamedTuple,
- compiler_kwargs::NamedTuple) where {F,launch}
- GC.@preserve f args begin
+@inline function compile_and_launch(
+ f::F, args::Tuple, ::Val{launch},
+ call_kwargs::NamedTuple,
+ compiler_kwargs::NamedTuple
+ ) where {F, launch}
+ return GC.@preserve f args begin
kernel_f = kernel_convert(f)
kernel_args = map(kernel_convert, args)
kernel_tt = Tuple{map(Core.Typeof, kernel_args)...}
diff --git a/test/execution.jl b/test/execution.jl
index d1babb8..8f3bdc1 100644
--- a/test/execution.jl
+++ b/test/execution.jl
@@ -313,30 +313,30 @@ end
end
-@testset "arguments of a union of singleton types" begin
- # JuliaLang/julia#63482: `GC.@preserve` of such a value crashed codegen
- function kernel(a, op)
- @inbounds a[1] = op(a[1], Int16(1))
- return
- end
+ @testset "arguments of a union of singleton types" begin
+ # JuliaLang/julia#63482: `GC.@preserve` of such a value crashed codegen
+ function kernel(a, op)
+ @inbounds a[1] = op(a[1], Int16(1))
+ return
+ end
- function compile(a)
- kernels = []
- for op in (max, min)
- push!(kernels, @oneapi launch=false kernel(a, op))
+ function compile(a)
+ kernels = []
+ for op in (max, min)
+ push!(kernels, @oneapi launch = false kernel(a, op))
+ end
+ kernels
end
- kernels
- end
- @test length(compile(oneArray(Int16[5]))) == 2
+ @test length(compile(oneArray(Int16[5]))) == 2
- function launch(a)
- for op in (max, min)
- @oneapi kernel(a, op)
+ function launch(a)
+ for op in (max, min)
+ @oneapi kernel(a, op)
+ end
+ Array(a)
end
- Array(a)
+ @test launch(oneArray(Int16[5])) == Int16[1]
end
- @test launch(oneArray(Int16[5])) == Int16[1]
-end
@testset "immutables" begin |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #685 +/- ##
==========================================
- Coverage 81.17% 80.62% -0.56%
==========================================
Files 52 51 -1
Lines 4085 3963 -122
==========================================
- Hits 3316 3195 -121
+ Misses 769 768 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
@oneapipreserved its arguments withGC.@preservedirectly in the caller's code. There an argument can be a union of singleton types, like the function infor op in (max, min). On Julia 1.12 and 1.13.0–1.13.1, codegen passes a null operand togc_preserve_beginfor such a value, and LLVM'sLazyCallGraphsegfaults while compiling the caller (JuliaLang/julia#63482). The upstream fix, JuliaLang/julia#63483, is onrelease-1.13but not yet in a release, and hasn't been backported to 1.12.This moves the body of the expansion into an inlined
compile_and_launchfunction, as CUDA.jl does. The arguments now have concrete types where they're preserved: the call is either split per type and inlined, or dispatched dynamically. For inferred call sites the generated code is the same as before. Call sites whose argument types aren't inferred now dispatch once instead of at each step, which saves 160 bytes per launch for@oneapi k(args...)withargs::Vector{Any}.Fixes #669