-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
add --static-call-graph option for generating smaller binaries #55047
Draft
JeffBezanson
wants to merge
26
commits into
master
Choose a base branch
from
jb/gb/static-call-graph
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains 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
also implement a --strict mode where generating a dynamic dispatch becomes a compile time error
…Also refactor the runtime to only have one option
Union split test gives the wrong result
1M binary on Mac M-series:
|
…. hacks) A lot of these changes will not be directly upstreamable, but this sketches out the direction we'll have to go in to type-stabilize these interfaces.
topolarity
added a commit
that referenced
this pull request
Jul 13, 2024
TypedCallable provides a wrapper for callable objects, with the following benefits: 1. Enforced type-stability (for concrete AT/RT types) 2. Fast calling convention (frequently < 10 ns / call) 3. Normal Julia dispatch semantics (sees new Methods, etc.) + invoke_latest 4. Pre-compilation support (including `--trim` compatibility) It can be used like this: ```julia callbacks = @TypedCallable{(::Int,::Int)->Bool}[] register_callback!(callbacks, f::F) where {F<:Function} = push!(callbacks, @TypedCallable f(::Int,::Int)::Bool) register_callback!(callbacks, (x,y)->(x == y)) register_callback!(callbacks, (x,y)->(x != y)) @Btime callbacks[rand(1:2)](1,1) ``` This is very similar to the existing `FunctionWrappers.jl`, but there are a few key differences: - Better type support: TypedCallable supports the full range of Julia types (incl. Varargs), and it has access to all of Julia's "internal" calling conventions so calls are fast (and allocation-free) for a wider range of input types - Improved dispatch handling: The `@cfunction` functionality used by FunctionWrappers has several dispatch bugs, which cause wrappers to occasionally not see new Methods. These bugs are fixed (or soon to be fixed) for TypedCallable. - Pre-compilation support including for `juliac` / `--trim` (#55047) Many of the improvements here are actually thanks to the `OpaqueClosure` introduced by @Keno - This type just builds on top of OpaqueClosure to provide an interface with Julia's usual dispatch semantics.
topolarity
added a commit
that referenced
this pull request
Jul 13, 2024
TypedCallable provides a wrapper for callable objects, with the following benefits: 1. Enforced type-stability (for concrete AT/RT types) 2. Fast calling convention (frequently < 10 ns / call) 3. Normal Julia dispatch semantics (sees new Methods, etc.) + invoke_latest 4. Pre-compilation support (including `--trim` compatibility) It can be used like this: ```julia callbacks = @TypedCallable{(::Int,::Int)->Bool}[] register_callback!(callbacks, f::F) where {F<:Function} = push!(callbacks, @TypedCallable f(::Int,::Int)::Bool) register_callback!(callbacks, (x,y)->(x == y)) register_callback!(callbacks, (x,y)->(x != y)) @Btime callbacks[rand(1:2)](1,1) ``` This is very similar to the existing `FunctionWrappers.jl`, but there are a few key differences: - Better type support: TypedCallable supports the full range of Julia types (incl. Varargs), and it has access to all of Julia's "internal" calling conventions so calls are fast (and allocation-free) for a wider range of input types - Improved dispatch handling: The `@cfunction` functionality used by FunctionWrappers has several dispatch bugs, which cause wrappers to occasionally not see new Methods. These bugs are fixed (or soon to be fixed) for TypedCallable. - Pre-compilation support including for `juliac` / `--trim` (#55047) Many of the improvements here are actually thanks to the `OpaqueClosure` introduced by @Keno - This type just builds on top of OpaqueClosure to provide an interface with Julia's usual dispatch semantics.
topolarity
added a commit
that referenced
this pull request
Jul 13, 2024
TypedCallable provides a wrapper for callable objects, with the following benefits: 1. Enforced type-stability (for concrete AT/RT types) 2. Fast calling convention (frequently < 10 ns / call) 3. Normal Julia dispatch semantics (sees new Methods, etc.) + invoke_latest 4. Pre-compilation support (including `--trim` compatibility) It can be used like this: ```julia callbacks = @TypedCallable{(::Int,::Int)->Bool}[] register_callback!(callbacks, f::F) where {F<:Function} = push!(callbacks, @TypedCallable f(::Int,::Int)::Bool) register_callback!(callbacks, (x,y)->(x == y)) register_callback!(callbacks, (x,y)->(x != y)) @Btime callbacks[rand(1:2)](1,1) ``` This is very similar to the existing `FunctionWrappers.jl`, but there are a few key differences: - Better type support: TypedCallable supports the full range of Julia types (incl. Varargs), and it has access to all of Julia's "internal" calling conventions so calls are fast (and allocation-free) for a wider range of input types - Improved dispatch handling: The `@cfunction` functionality used by FunctionWrappers has several dispatch bugs, which cause wrappers to occasionally not see new Methods. These bugs are fixed (or soon to be fixed) for TypedCallable. - Pre-compilation support including for `juliac` / `--trim` (#55047) Many of the improvements here are actually thanks to the `OpaqueClosure` introduced by @Keno - This type just builds on top of OpaqueClosure to provide an interface with Julia's usual dispatch semantics.
3 tasks
topolarity
added a commit
that referenced
this pull request
Jul 13, 2024
TypedCallable provides a wrapper for callable objects, with the following benefits: 1. Enforced type-stability (for concrete AT/RT types) 2. Fast calling convention (frequently < 10 ns / call) 3. Normal Julia dispatch semantics (sees new Methods, etc.) + invoke_latest 4. Pre-compilation support (including `--trim` compatibility) It can be used like this: ```julia callbacks = @TypedCallable{(::Int,::Int)->Bool}[] register_callback!(callbacks, f::F) where {F<:Function} = push!(callbacks, @TypedCallable f(::Int,::Int)::Bool) register_callback!(callbacks, (x,y)->(x == y)) register_callback!(callbacks, (x,y)->(x != y)) @Btime callbacks[rand(1:2)](1,1) ``` This is very similar to the existing `FunctionWrappers.jl`, but there are a few key differences: - Better type support: TypedCallable supports the full range of Julia types (incl. Varargs), and it has access to all of Julia's "internal" calling conventions so calls are fast (and allocation-free) for a wider range of input types - Improved dispatch handling: The `@cfunction` functionality used by FunctionWrappers has several dispatch bugs, which cause wrappers to occasionally not see new Methods. These bugs are fixed (or soon to be fixed) for TypedCallable. - Pre-compilation support including for `juliac` / `--trim` (#55047) Many of the improvements here are actually thanks to the `OpaqueClosure` introduced by @Keno - This type just builds on top of OpaqueClosure to provide an interface with Julia's usual dispatch semantics.
topolarity
added a commit
that referenced
this pull request
Jul 13, 2024
TypedCallable provides a wrapper for callable objects, with the following benefits: 1. Enforced type-stability (for concrete AT/RT types) 2. Fast calling convention (frequently < 10 ns / call) 3. Normal Julia dispatch semantics (sees new Methods, etc.) + invoke_latest 4. Pre-compilation support (including `--trim` compatibility) It can be used like this: ```julia callbacks = @TypedCallable{(::Int,::Int)->Bool}[] register_callback!(callbacks, f::F) where {F<:Function} = push!(callbacks, @TypedCallable f(::Int,::Int)::Bool) register_callback!(callbacks, (x,y)->(x == y)) register_callback!(callbacks, (x,y)->(x != y)) @Btime callbacks[rand(1:2)](1,1) ``` This is very similar to the existing `FunctionWrappers.jl`, but there are a few key differences: - Better type support: TypedCallable supports the full range of Julia types (incl. Varargs), and it has access to all of Julia's "internal" calling conventions so calls are fast (and allocation-free) for a wider range of input types - Improved dispatch handling: The `@cfunction` functionality used by FunctionWrappers has several dispatch bugs, which cause wrappers to occasionally not see new Methods. These bugs are fixed (or soon to be fixed) for TypedCallable. - Pre-compilation support including for `juliac` / `--trim` (#55047) Many of the improvements here are actually thanks to the `OpaqueClosure` introduced by @Keno - This type just builds on top of OpaqueClosure to provide an interface with Julia's usual dispatch semantics. Co-authored-by: Gabriel Baraldi <[email protected]>
#55104 gets the lib example working |
Let me know if issues should be raised elsewhere, but I ran into a problem where the compiled binaries don't seem to get # args.jl
module ArgsDemo
Base.@ccallable function main()::Cint
ccall(:jl_, Cvoid, (Any,), ARGS)
return 0
end
end
|
Note this is a PR against #55047 Co-authored by: Gabriel Baraldi <[email protected]>
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.
This adds a command line option
--static-call-graph
that builds images where code is only included if it is statically reachable from methods marked using the new functionentrypoint
. Compile-time errors are given for call sites that are too dynamic to allow trimming the call graph (however there is anunsafe
option if you want to try building anyway to see what happens).The PR has two other components. One is changes to Base that generally allow more code to be compiled in this mode. These changes will either be merged in separate PRs or moved to a separate part of the workflow (where we will build a custom system image for this purpose). The branch is set up this way to make it easy to check out and try the functionality.
The other component is everything in the
juliac/
directory, which implements a compiler driver script based on this new option, along with some examples and tests. This will eventually become a package "app" that depends on PackageCompiler and provides a CLI for all of this stuff, so it will not be merged here. To try an example:When stripped the resulting executable is currently about 900kb on my machine.
Note the script calls this
--trim
, which will be the official name of this option (following similar functionality in .NET). It is not yet clear if this is identical to the internal--static-call-graph
option, or if the latter is an implementation detail of the former.Also includes a lot of work by @topolarity