Skip to content

Add check_only option to precompile #58146

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

Closed
wants to merge 1 commit into from
Closed

Add check_only option to precompile #58146

wants to merge 1 commit into from

Conversation

kpamnany
Copy link
Member

@kpamnany kpamnany commented Apr 16, 2025

We want to compile a subset of the possible specializations of a function. To this end, we have a number of manually written precompile statements. Creating this list is, unfortunately, error-prone, and the list is also liable to going stale. Thus we'd like to validate each precompile statement in the list.

The simple answer is, of course, to actually run the precompiles, and we naturally do so, but this takes time.

We would like a relatively quick way to check the validity of a precompile statement.
This is a dev-loop optimization, to allow us to check "is-precompilable" in unit tests.

We can't use hasmethod as it has both false positives (too loose):

julia> hasmethod(sum, (AbstractVector,))
true

julia> precompile(sum, (AbstractVector,))
false

julia> precompile(sum, (AbstractVector,); check_only=true) # <- this PR
false

and also false negatives (too strict):

julia> bar(@nospecialize(x::AbstractVector{Int})) = 42
bar (generic function with 1 method)

julia> hasmethod(bar, (AbstractVector,))
false

julia> precompile(bar, (AbstractVector,))
true

julia> precompile(bar, (AbstractVector,); check_only=true) # <- this PR
true

We can't use hasmethod && isconcretetype as it has false negatives (too strict):

julia> has_concrete_method(f, argtypes) = all(isconcretetype, argtypes) && hasmethod(f, argtypes)
has_concrete_method (generic function with 1 method)

julia> has_concrete_method(bar, (AbstractVector,))
false

julia> has_concrete_method(convert, (Type{Int}, Int32))
false

julia> precompile(convert, (Type{Int}, Int32))
true

julia> precompile(convert, (Type{Int}, Int32); check_only=true)  # <- this PR
true

This PR adds the check_only Bool keyword argument to precompile; if true, the method instance isn't actually compiled. We can, of course, add a new isprecompilable instead, or move things around.

Cc: @nickrobinson251 whose idea this is, @gbaraldi who suggested opening the PR for discussion, and @JeffBezanson who had some thoughts on "compilability".

@NHDaly NHDaly requested a review from gbaraldi June 18, 2025 14:54
@NHDaly NHDaly marked this pull request as ready for review June 18, 2025 14:54
@gbaraldi
Copy link
Member

Maybe add a isprecompilable option that's similar to hasmethod but that uses the jl_get_compile_hint_specialization logic that compile_hint has.

@IanButterworth
Copy link
Member

IanButterworth commented Jun 20, 2025

Can you just run the original precompile statements in a --compile=no session?
It still gives the correct false here.

./julia --compile=no -e "Base.@trace_compile @show precompile(sum, (AbstractVector,))"
precompile(sum, (AbstractVector,)) = false

@kpamnany
Copy link
Member Author

Maybe add a isprecompilable option that's similar to hasmethod but that uses the jl_get_compile_hint_specialization logic that compile_hint has.

See #58805.

@kpamnany
Copy link
Member Author

@IanButterworth: starting a new process for this seems like a heavyweight solution.

@IanButterworth
Copy link
Member

I thought the benefit of only having to construct your precompile statements outweighed that. Then you know for sure you're testing the right thing.

Maybe something like this instead?

@compile_no include("precompile_statements.jl")

kpamnany added a commit that referenced this pull request Jul 2, 2025
Alternative to #58146.

We want to compile a subset of the possible specializations of a
function. To this end, we have a number of manually written `precompile`
statements. Creating this list is, unfortunately, error-prone, and the
list is also liable to going stale. Thus we'd like to validate each
`precompile` statement in the list.

The simple answer is, of course, to actually run the `precompile`s, and
we naturally do so, but this takes time.

We would like a relatively quick way to check the validity of a
`precompile` statement.
This is a dev-loop optimization, to allow us to check "is-precompilable"
in unit tests.

We can't use `hasmethod` as it has both false positives (too loose):
```julia
julia> hasmethod(sum, (AbstractVector,))
true

julia> precompile(sum, (AbstractVector,))
false

julia> Base.isprecompilable(sum, (AbstractVector,)) # <- this PR
false
```
and also false negatives (too strict):
```julia
julia> bar(@nospecialize(x::AbstractVector{Int})) = 42
bar (generic function with 1 method)

julia> hasmethod(bar, (AbstractVector,))
false

julia> precompile(bar, (AbstractVector,))
true

julia> Base.isprecompilable(bar, (AbstractVector,)) # <- this PR
true
```
We can't use `hasmethod && isconcretetype` as it has false negatives
(too strict):
```julia
julia> has_concrete_method(f, argtypes) = all(isconcretetype, argtypes) && hasmethod(f, argtypes)
has_concrete_method (generic function with 1 method)

julia> has_concrete_method(bar, (AbstractVector,))
false

julia> has_concrete_method(convert, (Type{Int}, Int32))
false

julia> precompile(convert, (Type{Int}, Int32))
true

julia> Base.isprecompilable(convert, (Type{Int}, Int32))  # <- this PR
true
```
`Base.isprecompilable` is essentially `precompile` without the actual
compilation.
@kpamnany
Copy link
Member Author

kpamnany commented Jul 2, 2025

Replaced by #58805.

@kpamnany kpamnany closed this Jul 2, 2025
@kpamnany kpamnany deleted the kp-npr-precomp branch July 2, 2025 16:29
NHDaly pushed a commit to RelationalAI/julia that referenced this pull request Jul 8, 2025
Alternative to JuliaLang#58146.

We want to compile a subset of the possible specializations of a
function. To this end, we have a number of manually written `precompile`
statements. Creating this list is, unfortunately, error-prone, and the
list is also liable to going stale. Thus we'd like to validate each
`precompile` statement in the list.

The simple answer is, of course, to actually run the `precompile`s, and
we naturally do so, but this takes time.

We would like a relatively quick way to check the validity of a
`precompile` statement.
This is a dev-loop optimization, to allow us to check "is-precompilable"
in unit tests.

We can't use `hasmethod` as it has both false positives (too loose):
```julia
julia> hasmethod(sum, (AbstractVector,))
true

julia> precompile(sum, (AbstractVector,))
false

julia> Base.isprecompilable(sum, (AbstractVector,)) # <- this PR
false
```
and also false negatives (too strict):
```julia
julia> bar(@nospecialize(x::AbstractVector{Int})) = 42
bar (generic function with 1 method)

julia> hasmethod(bar, (AbstractVector,))
false

julia> precompile(bar, (AbstractVector,))
true

julia> Base.isprecompilable(bar, (AbstractVector,)) # <- this PR
true
```
We can't use `hasmethod && isconcretetype` as it has false negatives
(too strict):
```julia
julia> has_concrete_method(f, argtypes) = all(isconcretetype, argtypes) && hasmethod(f, argtypes)
has_concrete_method (generic function with 1 method)

julia> has_concrete_method(bar, (AbstractVector,))
false

julia> has_concrete_method(convert, (Type{Int}, Int32))
false

julia> precompile(convert, (Type{Int}, Int32))
true

julia> Base.isprecompilable(convert, (Type{Int}, Int32))  # <- this PR
true
```
`Base.isprecompilable` is essentially `precompile` without the actual
compilation.
@NHDaly NHDaly mentioned this pull request Jul 8, 2025
3 tasks
NHDaly added a commit to RelationalAI/julia that referenced this pull request Jul 8, 2025
Alternative to JuliaLang#58146.

We want to compile a subset of the possible specializations of a
function. To this end, we have a number of manually written `precompile`
statements. Creating this list is, unfortunately, error-prone, and the
list is also liable to going stale. Thus we'd like to validate each
`precompile` statement in the list.

The simple answer is, of course, to actually run the `precompile`s, and
we naturally do so, but this takes time.

We would like a relatively quick way to check the validity of a
`precompile` statement.
This is a dev-loop optimization, to allow us to check "is-precompilable"
in unit tests.

We can't use `hasmethod` as it has both false positives (too loose):
```julia
julia> hasmethod(sum, (AbstractVector,))
true

julia> precompile(sum, (AbstractVector,))
false

julia> Base.isprecompilable(sum, (AbstractVector,)) # <- this PR
false
```
and also false negatives (too strict):
```julia
julia> bar(@nospecialize(x::AbstractVector{Int})) = 42
bar (generic function with 1 method)

julia> hasmethod(bar, (AbstractVector,))
false

julia> precompile(bar, (AbstractVector,))
true

julia> Base.isprecompilable(bar, (AbstractVector,)) # <- this PR
true
```
We can't use `hasmethod && isconcretetype` as it has false negatives
(too strict):
```julia
julia> has_concrete_method(f, argtypes) = all(isconcretetype, argtypes) && hasmethod(f, argtypes)
has_concrete_method (generic function with 1 method)

julia> has_concrete_method(bar, (AbstractVector,))
false

julia> has_concrete_method(convert, (Type{Int}, Int32))
false

julia> precompile(convert, (Type{Int}, Int32))
true

julia> Base.isprecompilable(convert, (Type{Int}, Int32))  # <- this PR
true
```
`Base.isprecompilable` is essentially `precompile` without the actual
compilation.

Co-authored-by: Kiran Pamnany <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants