-
Notifications
You must be signed in to change notification settings - Fork 10
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_methods function #8
Conversation
What if rather than dooing all this stuff to create a
So that, as you see does indeed compute the methods at compile time, but it is missing the hooks. But then we do the same thing we do in Probably extract out some common functionality between the two into helpers. |
So what happened with your investigation into whether the optimizer is already doing this? |
The optimizer won't do this, it might do the thing that was Mason's original use case for this though |
I'm not sure I understand exactly what you mean here
or how to achieve it. |
Like in my example we define at the start :
Then in our This we don't need to do the fiddly expr to codeinfo thing |
Yes, exactly! Then your whole function would basically just be like: @generated function static_methods(@nospecialize(m::Module), @nospecialize(f) , @nospecialize(_T::Type{T})) where {T <: Tuple}
# Re-use the body of _neomethods:
ci_orig = uncompressed_ast(typeof(_neomethods).name.mt.defs.func)
ci = ccall(:jl_copy_code_info, Ref{CodeInfo}, (Any,), ci_orig)
# And just add the edges so if a method is added to `f`, this recompiles
mt = f.name.mt
ci.edges = Core.Compiler.vect(mt, Tuple{Vararg{Any}})
return ci
end Or something else simple, more or less like that. :) I'm actually not even sure if |
Unfortunately, if If julia> begin
using Tricks
f(::Int) = 1
static_methods(f, Tuple{Any})
end
ERROR: Could not expand generator for `@generated` method MethodInstance for _neomethods(::typeof(f), ::Tuple{Any}). This can happen if the provided argument types (Tuple{typeof(f),Tuple{Any}}) are not leaf types, but the `generated` argument is `true`.
Stacktrace:
[1] error(::String, ::Core.MethodInstance, ::String, ::String, ::Type, ::String, ::String) at ./error.jl:42
[2] (::Base.var"#12#13"{Bool,DataType})(::Core.MethodInstance) at ./reflection.jl:806
[3] _collect(::Array{Core.MethodInstance,1}, ::Base.Generator{Array{Core.MethodInstance,1},Base.var"#12#13"{Bool,DataType}}, ::Base.EltypeUnknown, ::Base.HasShape{1}) at ./generator.jl:47
[4] collect_similar(::Array{Core.MethodInstance,1}, ::Base.Generator{Array{Core.MethodInstance,1},Base.var"#12#13"{Bool,DataType}}) at ./array.jl:564
[5] map(::Function, ::Array{Core.MethodInstance,1}) at ./abstractarray.jl:2073
[6] #code_lowered#11 at ./reflection.jl:801 [inlined]
[7] code_lowered at ./reflection.jl:793 [inlined]
[8] #s15#7 at /Users/mason/.julia/dev/Tricks/src/Tricks.jl:69 [inlined]
[9] #s15#7(::Any, ::Any, ::Any, ::Any) at none:0
[10] (::Core.GeneratedFunctionStub)(::Any, ::Vararg{Any,N} where N) at ./boot.jl:524
[11] top-level scope at REPL[1]:4 where the relevant code from Tricks is @generated _neomethods(@nospecialize(f), @nospecialize(t)) = methods(f, t)
@generated function static_methods(@nospecialize(f) , @nospecialize(_T::Type{T})) where {T <: Tuple}
# Re-use the body of _neomethods:
ci_orig = code_lowered(_neomethods, Tuple{f, T})
ci = ccall(:jl_copy_code_info, Ref{CodeInfo}, (Any,), ci_orig)
# And just add the edges so if a method is added to `f`, this recompiles
mt = f.name.mt
ci.edges = Core.Compiler.vect(mt, Tuple{Vararg{Any}})
return ci
end |
Unfortunately, if _neomethods is not @generated, then static_methods will
run at runtime, not compiletime.
Is that right? Even though `static_methods` itself is a @generated function?
…On Sun, Jan 19, 2020 at 2:50 PM Mason Protter ***@***.***> wrote:
Unfortunately, if _neomethods is not @generated, then static_methods will
run at runtime, not compiletime.
If _neomethods is @generated, then uncompressed_ast doesn't work and
julia suggests to use code_lowered instead, but when I switch to code_lowered(_neomethods,
Tuple{f, T}) I get
julia> begin
using Tricks
f(::Int) = 1
static_methods(f, Tuple{Any})
end
ERROR: Could not expand generator for ***@***.***` method MethodInstance for _neomethods(::typeof(f), ::Tuple{Any}). This can happen if the provided argument types (Tuple{typeof(f),Tuple{Any}}) are not leaf types, but the `generated` argument is `true`.
Stacktrace:
[1] error(::String, ::Core.MethodInstance, ::String, ::String, ::Type, ::String, ::String) at ./error.jl:42
[2] (::Base.var"#12#13"{Bool,DataType})(::Core.MethodInstance) at ./reflection.jl:806
[3] _collect(::Array{Core.MethodInstance,1}, ::Base.Generator{Array{Core.MethodInstance,1},Base.var"#12#13"{Bool,DataType}}, ::Base.EltypeUnknown, ::Base.HasShape{1}) at ./generator.jl:47
[4] collect_similar(::Array{Core.MethodInstance,1}, ::Base.Generator{Array{Core.MethodInstance,1},Base.var"#12#13"{Bool,DataType}}) at ./array.jl:564
[5] map(::Function, ::Array{Core.MethodInstance,1}) at ./abstractarray.jl:2073
[6] #code_lowered#11 at ./reflection.jl:801 [inlined]
[7] code_lowered at ./reflection.jl:793 [inlined]
[8] #s15#7 at /Users/mason/.julia/dev/Tricks/src/Tricks.jl:69 [inlined]
[9] #s15#7(::Any, ::Any, ::Any, ::Any) at none:0
[10] (::Core.GeneratedFunctionStub)(::Any, ::Vararg{Any,N} where N) at ./boot.jl:524
[11] top-level scope at REPL[1]:4
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#8?email_source=notifications&email_token=AAMCIELIYXSXUC3OTOMGSM3Q6SVINA5CNFSM4KIPDOJ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJK2XSI#issuecomment-576039881>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAMCIEMPXMXTPXNC5LSM5F3Q6SVINANCNFSM4KIPDOJQ>
.
|
That’s what I saw testing it myself. It’s possible I did something incorrect though. |
hmm, I will have a play with this for a big see if i can make it work. |
I couldn't work it out either. |
Okay, will do. |
Okay, so I'd updated the docstring, switched to Tests pass locally. Maybe we should get Travis set up for this package? |
I have added Travis. If you rebase off master is should run. Can you also bump the version in the Project.toml so i can tag a release? |
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.
Unfortunately, if _neomethods is not @generated, then static_methods will run at runtime, not compiletime.
Is that right? Even though
static_methods
itself is a @generated function?
Oh, wait, right, duh, of course that's right. Because now the method you're generating has as its body, a runtime call to methods()
, rather than having as its body the result of a call to methods from within the generated function. ✔️
I think the code as you have it is the best way to do what you want: you call methods()
from within the body of the generated function, then you create a new CodeInfo that does nothing but return that result, and attach edges to it! ✔️
Co-Authored-By: Lyndon White <[email protected]>
…ks.jl into static_methods
I think the CI failures are unrelated. |
urg, those test failures are unrelated yes. I need to work out a better way to test these thins |
@MasonProtter can you take a look at the commit I just mad and see that i didn't break anything? I also note that since sparams is never
But I think that might make the code less clear |
Your commit looks good to me and the tests pass locally. |
This is the result of some explorations I took in finding all the methods of a function at compile time, with back-edges built in.
As you can see it happens at compile time, but also gets recompiled when new methods are added:
I messed with the indentation to reflect regular module organization, but if you don't like that I can revert it.