-
Notifications
You must be signed in to change notification settings - Fork 233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for Julia 1.11 #2241
Comments
Testing on backports-release-1.11@JuliaLang/julia@b69fc57, which includes JuliaLang/julia#54323, this does not seem to fix the third MWE here:
@aviatesk I thought you mentioned otherwise in JuliaLang/julia#54322 (comment)? |
I have confirmed that the original issue (JuliaLang/julia#52938) has been fixed in const CC = Core.Compiler
using Core: MethodInstance, CodeInstance, CodeInfo, MethodTable
## interpreter
if isdefined(CC, :CachedMethodTable)
const ExternalMethodTableView = CC.CachedMethodTable{CC.OverlayMethodTable}
get_method_table_view(world::UInt, mt::MethodTable) =
CC.CachedMethodTable(CC.OverlayMethodTable(world, mt))
else
const ExternalMethodTableView = CC.OverlayMethodTable
get_method_table_view(world::UInt, mt::MethodTable) = CC.OverlayMethodTable(world, mt)
end
struct ExternalInterpreter <: CC.AbstractInterpreter
world::UInt
method_table::ExternalMethodTableView
# code_cache
inf_cache::Vector{CC.InferenceResult}
end
function ExternalInterpreter(world::UInt=Base.get_world_counter(); method_table)
@assert world <= Base.get_world_counter()
method_table = get_method_table_view(world, method_table)
inf_cache = Vector{CC.InferenceResult}()
return ExternalInterpreter(world, method_table, inf_cache)
end
CC.InferenceParams(interp::ExternalInterpreter) = CC.InferenceParams()
CC.OptimizationParams(interp::ExternalInterpreter) = CC.OptimizationParams()
CC.get_inference_world(interp::ExternalInterpreter) = interp.world
CC.get_inference_cache(interp::ExternalInterpreter) = interp.inf_cache
CC.cache_owner(interp::ExternalInterpreter) = Symbol("JuliaLang/julia#52938")
# No need to do any locking since we're not putting our results into the runtime cache
CC.lock_mi_inference(interp::ExternalInterpreter, mi::MethodInstance) = nothing
CC.unlock_mi_inference(interp::ExternalInterpreter, mi::MethodInstance) = nothing
function CC.add_remark!(interp::ExternalInterpreter, sv::CC.InferenceState, msg)
@debug "Inference remark during External compilation of $(sv.linfo): $msg"
end
CC.may_optimize(interp::ExternalInterpreter) = true
CC.may_compress(interp::ExternalInterpreter) = true
CC.may_discard_trees(interp::ExternalInterpreter) = true
CC.verbose_stmt_info(interp::ExternalInterpreter) = false
CC.method_table(interp::ExternalInterpreter) = interp.method_table
# main
Base.Experimental.@MethodTable(GLOBAL_METHOD_TABLE)
inner(f, types::Type, args...; kwargs...) = nothing
outer(f) = @inline inner(f, Tuple{}; foo=Ref(42), bar=1)
interp = ExternalInterpreter(; method_table=GLOBAL_METHOD_TABLE)
only(Base.code_ircode(outer, Tuple{Nothing}; interp))
So, it seems likely that there is some interaction with the implementation of CUDA's external abstract interpreter? |
@maleadt Can you share with me an example to run external abstract interpreter used CUDA.jl, in a way that doesn't require any CUDA driver installed? |
Looks like one of the quirks is a contributing factor here. Adding the following overlay mimics that: Base.Experimental.@overlay GLOBAL_METHOD_TABLE @inline Base.throw_boundserror(A, I) = error() |
I see, in that case, it seems necessary to use JuliaLang/julia#54322 and mark |
Yeah, I confirmed it fixes the issue if we overlay it as |
FWIW, t actual implementation does some more work: Lines 10 to 17 in e1e5be2
But it still ends in an unconditional |
Ah I see, so our situation is trickier than I thought... In this case, both the original and In this case, the original version is macro gputhrow(subtype, reason)
quote Base.@assume_effects :effect_free begin
info = kernel_state().exception_info
info.subtype = @strptr $subtype
info.reason = @strptr $reason
throw(nothing)
end end
end , which is totally wrong usage of In this case I think it might be a good solution to incorporate an idea like struct GPUError
subtype
reason
end
macro gputhrow(subtype, reason)
:(GPUError($subtype, $reason))
end
function Base.show_error(io::IO, x::GPUError) # delay the effect of `@gputhrow`
info = kernel_state().exception_info
info.subtype = @strptr x.subtype
info.reason = @strptr x.reason
[...] # show the proper exception using the updated kernel state here?
end The goal of this implementation is to delay the computational effects of |
Sadly not, we don't support try/catch in GPU code (stack unwinding, and setjmp/longjmp are not supported), so we can't actually throw an error object for evaluation outside of the code generated by |
@maleadt After further investigation, it seems that simply using |
I see. I hope effect mismatches from our other overrides (i.e. outside of the julia> Base.infer_effects(Base.cos, (Float32,))
(+c,+e,!n,+t,+s,+m,+i)
julia> cuda_cos(x::Float32) = ccall("extern __nv_cosf", llvmcall, Cfloat, (Cfloat,), x)
cuda_cos (generic function with 1 method)
julia> Base.infer_effects(cuda_cos, (Float32,))
(!c,!e,!n,!t,!s,!m,+i) Or our julia> Base.infer_effects(Base.:(^), (Float64, Int64))
(+c,+e,+n,+t,+s,+m,+i)
julia> function cuda_pow(x::Float64, y::Int64)
y == -1 && return inv(x)
y == 0 && return one(x)
y == 1 && return x
y == 2 && return x*x
y == 3 && return x*x*x
x ^ Float64(y)
end
cuda_pow (generic function with 1 method)
julia> Base.infer_effects(cuda_pow, (Float64, Int64))
(+c,+e,!n,+t,+s,+m,+i) Again, me having doubts here is purely because of not fully understanding the effects analysis. Which is why I expressed some reservations in JuliaLang/julia#54322 (comment). |
Even if the effects mismatch, there is no problem using
As long as these conditions are met, there is no problem using |
Thanks, that really helps! |
Blocked on: JuliaLang/julia#52938
MWEs for that issue (in descending order of abstraction):
The text was updated successfully, but these errors were encountered: