-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Can we support a way to make @code_typed
stop lying to us all? :)
#32834
Comments
CC: @vtjnash (opening this issue based on our conversation) |
There's this: #23749 |
I like the idea of adding a keyword argument that would let you choose! |
Maybe a keyword argument called
|
I propose to name the keywords |
Another options would be |
Interestingly enough, the behavior is different for keyword arguments vs positional arguments. As an example: julia> f(x) = Base.typemax(x)
f (generic function with 1 method)
julia> g(; y) = Base.typemax(y)
g (generic function with 1 method)
julia> @code_typed f(Int)
CodeInfo(
1 ─ return 9223372036854775807
) => Int64
julia> @code_typed g(y = Int)
CodeInfo(
1 ── %1 = Base.getfield(@_2, :y)::DataType
│ %2 = Base.sle_int(1, 1)::Bool
└─── goto #3 if not %2
2 ── %4 = Base.sle_int(1, 0)::Bool
└─── goto #4
3 ── nothing::Nothing
4 ┄─ %7 = φ (#2 => %4, #3 => false)::Bool
└─── goto #6 if not %7
5 ── invoke Base.getindex(()::Tuple, 1::Int64)::Union{}
└─── $(Expr(:unreachable))::Union{}
6 ┄─ goto #7
7 ── goto #8
8 ── goto #9
9 ── goto #10
10 ─ nothing::Nothing
│ %16 = invoke Main.:(var"#g#3")(%1::Type, _3::typeof(g))::Any
└─── return %16
) => Any @NHDaly Any idea why |
@DilumAluthge Yeah, i think I remember reading once that Julia doesn't specialize on keyword arguments at all, period. So the julia> @btime f(Int)
0.035 ns (0 allocations: 0 bytes)
9223372036854775807
julia> @btime g(y=Int)
44.038 ns (0 allocations: 0 bytes)
9223372036854775807 |
Are you sure? The following example makes it seem like Julia is specializing on keyword arguments. julia> foo(; x) = x + x + x
foo (generic function with 1 method)
julia> @code_native foo(; x = 1)
.section __TEXT,__text,regular,pure_instructions
; ┌ @ REPL[1]:1 within `foo##kw'
; │┌ @ REPL[1]:1 within `#foo#3'
; ││┌ @ operators.jl:529 within `+' @ REPL[1]:1
imulq $3, (%rdi), %rax
; │└└
retq
nopw %cs:(%rax,%rax)
; └
julia> @code_native foo(; x = 1.0)
.section __TEXT,__text,regular,pure_instructions
; ┌ @ REPL[1]:1 within `foo##kw'
; │┌ @ REPL[1]:1 within `#foo#3'
; ││┌ @ operators.jl:529 within `+' @ REPL[1]:1
vmovsd (%rdi), %xmm0 ## xmm0 = mem[0],zero
vaddsd %xmm0, %xmm0, %xmm1
vaddsd %xmm1, %xmm0, %xmm0
; │└└
retq
nopl (%rax)
; └ |
That is not true. With some will you can dig through things: julia> f(x=1; y=2, z=3) = x + y + z
f (generic function with 2 methods)
julia> @code_warntype Core.kwfunc(f)((z=2,y=1,), f, 1)
Body::Int64
....
7 ┄ %21 = Main.:(var"#f#7")(y, z, @_3, x)::Int64
└── return %21
julia> @code_warntype var"#f#7"(1, 2, f, 2)
Variables
#f#7::Core.Compiler.Const(#f#7, false)
y::Int64
z::Int64
@_4::Core.Compiler.Const(f, false)
x::Int64
Body::Int64
1 ─ %1 = (x + y + z)::Int64
└── return %1
julia> @code_warntype var"#f#7"(1, 2.0, f, 2)
Variables
#f#7::Core.Compiler.Const(#f#7, false)
y::Int64
z::Float64
@_4::Core.Compiler.Const(f, false)
x::Int64
Body::Float64
1 ─ %1 = (x + y + z)::Float64
└── return %1 So the innermost function ( |
Are julia> f1(x) = Base.typemax(x)
f1 (generic function with 1 method)
julia> @code_native f1(Int)
.text
; ┌ @ REPL[2]:1 within `f1'
movabsq $9223372036854775807, %rax # imm = 0x7FFFFFFFFFFFFFFF
retq
nopl (%rax,%rax)
; └ Or has something changed and the example at the top is no longer relevant for this issue? |
Yes, that is the same "lie" that's demonstrated in the first post by See https://docs.julialang.org/en/v1/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing for more details. |
With Cthulhu it depends on how you get there; if you ask from top level you'll get the same result you do for the macros. But if you get to it via the normal calling path then I think it mostly gets the answer right. I may have still seen one exception so I don't want to claim it too strongly, but fundamentally now (and only on 1.7+) what Cthulhu does is re-use the inference work that normally gets done by the compiler. |
@code_typed
(andcode_typed
) will sometimes report a different result than actually gets inferred if you call the function. For example:Here
@code_typed
shows you fully specialized code, even though in reality this call will not be specialized (it will be a dynamic dispatch totypemax(Type{Int})
).xref: the documentation change here: #32817
Could we either change
@code_typed
or add a flag to@code_typed
that will show you the code as julia would actually specialize it, instead of fully specialized to your argument type? :)The text was updated successfully, but these errors were encountered: