-
Notifications
You must be signed in to change notification settings - Fork 0
Expose function to check if precompile
guaranteed to fail (similar to hasmethod
)
#228
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
base: v1.10.2+RAI
Are you sure you want to change the base?
Conversation
@@ -2942,6 +2942,19 @@ JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types) | |||
return 1; | |||
} | |||
|
|||
// true if jl_get_compile_hint_specialization can find a method instance for us to try | |||
// to compile | |||
JL_DLLEXPORT int jl_has_compile_hint_specialization(jl_tupletype_t *types) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is just jl_compile_hint
from above (which is what precompile(f, argtypes)
calls), but without the jl_compile_method_instance
call
size_t world = jl_atomic_load_acquire(&jl_world_counter); | ||
size_t min_valid = 0; | ||
size_t max_valid = ~(size_t)0; | ||
jl_method_instance_t *mi = jl_get_compile_hint_specialization(types, world, &min_valid, &max_valid, 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jl_get_compile_hint_specialization
first finds a "compilable method match" then calls jl_method_match_to_mi
to create a "method instance" -- if that step can't return NULL
then i suppose we don't need to spend the time creating the "method instance" and could just check if we found a "method match" ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah interesting. i'm not sure whether that step is generally nullable or not. 🤔
The code you have here, now, roughly matches what i had in mind when you described this idea to me 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kpamnany is going to ask Gabriel about this
precompile
guaranteed to failprecompile
guaranteed to fail (similar to hasmethod
but stricter)
precompile
guaranteed to fail (similar to hasmethod
but stricter)precompile
guaranteed to fail (similar to hasmethod
)
function precompilable(@nospecialize(f), @nospecialize(argtypes::Tuple)) | ||
precompile(Tuple{Core.Typeof(f), argtypes...}) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we could call this has_method_instance_match
?
module PrecompilableTest | ||
foo(v::AbstractVector) = first(v) +1 | ||
end | ||
@testset "precompilable" begin | ||
@test !Base.precompilable(PrecompilableTest.foo, (AbstractVector,)) | ||
@test !Base.precompilable(PrecompilableTest.foo, (AbstractVector{Int},)) | ||
@test !Base.precompilable(PrecompilableTest.foo, (Vector,)) | ||
@test Base.precompilable(PrecompilableTest.foo, (Vector{Int},)) | ||
@test hasmethod(PrecompilableTest.foo, (AbstractVector,)) | ||
@test hasmethod(PrecompilableTest.foo, (AbstractVector{Int},)) | ||
@test hasmethod(PrecompilableTest.foo, (Vector,)) | ||
@test hasmethod(PrecompilableTest.foo, (Vector{Int},)) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to add tests for all the false positive and false negative cases in the PR description?
PR Description
What does this PR do?
adds a function to check if a
precompile
statement will have no effectuse-case
precompile
calls are valid?precompiles
and throw is they fail, likeprecompile(...) || @assert false
, but this means we have to actually wait for the compilation to happen (which is prohibitively slow)precompile(f, argtypes)
to fail is because their is no method specialization forf
with thoseargtypes
(as opposed to because compilation of such a method specialization fails), and that we can check with the function added in this PR!i should run some timings but undoubtedly looking up a method specialization is the faster part compared to actually compiling, so this (I believe) strikes a good balance of being useful enough and fast enough.
We can't use
hasmethod
as it has both false positives (too loose):and also false negatives (too strict):
We can't use e.g.
hasmethod && isconcretype
as it has false negatives (too strict):Open questions
isprecompilable
?has_precompilable_specialization
?has_precompilable_method
?loading.jl
next toprecompile
or inreflection.jl
next tohasmethod
?public
(if opened upstream)?Checklist
Requirements for merging:
port-to-*
labels that don't apply.