Skip to content
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

Use depth-limited type printing #601

Merged

Conversation

charleskawczynski
Copy link
Contributor

@charleskawczynski charleskawczynski commented Jan 29, 2024

Add depth-limited type printing.

This PR takes advantage of JuliaLang/julia#49795 by truncating the printing of types.

I'm sure that not all of these changes are needed, and we probably want to change or expose changing some parameters, but this reproducer does work for me:

Full reproducer

using Revise
import JET
struct F49231{a,b,c,d,e,f,g}
	num::g
end;
f = F49231{Float64,Float32,Int,String,AbstractString,6,Float64}(1);
bar(x) = rand() > 0.5 ? x : Any[0][1]
mysum(x) = sum(y-> bar(x.num), 1:5; init=0)
a = Any[f];
mysum(a[1]) # make sure it runs
JET.@test_opt mysum(a[1])

Results, main:

JET-test failed at REPL[8]:1
  Expression: #= REPL[8]:1 =# JET.@test_opt mysum(a[1])
  ═════ 5 possible errors found ═════
  ┌ mysum(x::F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}) @ Main ./REPL[6]:1
  │┌ kwcall(::@NamedTuple{init::Int64}, ::typeof(sum), f::var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, a::UnitRange{Int64}) @ Base ./reducedim.jl:1011
  ││┌ sum(f::var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, a::UnitRange{Int64}; dims::Colon, kw::@Kwargs{init::Int64}) @ Base ./reducedim.jl:1011
  │││┌ kwcall(::@NamedTuple{init::Int64}, ::typeof(Base._sum), f::var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, a::UnitRange{Int64}, ::Colon) @ Base ./reducedim.jl:1015
  ││││┌ _sum(f::var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, a::UnitRange{Int64}, ::Colon; kw::@Kwargs{init::Int64}) @ Base ./reducedim.jl:1015
  │││││┌ kwcall(::@NamedTuple{init::Int64}, ::typeof(mapreduce), f::var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, op::typeof(Base.add_sum), A::UnitRange{Int64}) @ Base ./reducedim.jl:357
  ││││││┌ mapreduce(f::var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, op::typeof(Base.add_sum), A::UnitRange{Int64}; dims::Colon, init::Int64) @ Base ./reducedim.jl:357
  │││││││┌ _mapreduce_dim(f::var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, op::typeof(Base.add_sum), nt::Int64, A::UnitRange{Int64}, ::Colon) @ Base ./reducedim.jl:362
  ││││││││┌ mapfoldl_impl(f::var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, op::typeof(Base.add_sum), nt::Int64, itr::UnitRange{Int64}) @ Base ./reduce.jl:44
  │││││││││┌ foldl_impl(op::Base.MappingRF{var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, Base.BottomRF{typeof(Base.add_sum)}}, nt::Int64, itr::UnitRange{Int64}) @ Base ./reduce.jl:48
  ││││││││││┌ _foldl_impl(op::Base.MappingRF{var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, Base.BottomRF{typeof(Base.add_sum)}}, init::Int64, itr::UnitRange{Int64}) @ Base ./reduce.jl:58
  │││││││││││┌ (::Base.MappingRF{var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, Base.BottomRF{typeof(Base.add_sum)}})(acc::Int64, x::Int64) @ Base ./reduce.jl:100
  ││││││││││││┌ (::Base.BottomRF{typeof(Base.add_sum)})(acc::Int64, x::Any) @ Base ./reduce.jl:86
  │││││││││││││ runtime dispatch detected: add_sum(acc::Int64, x::Any)::Any
  ││││││││││││└────────────────────
  ││││││││││┌ _foldl_impl(op::Base.MappingRF{var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, Base.BottomRF{typeof(Base.add_sum)}}, init::Int64, itr::UnitRange{Int64}) @ Base ./reduce.jl:62
  │││││││││││┌ (::Base.MappingRF{var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, Base.BottomRF{typeof(Base.add_sum)}})(acc::Any, x::Int64) @ Base ./reduce.jl:100
  ││││││││││││┌ (::Base.BottomRF{typeof(Base.add_sum)})(::Base._InitialValue, x::Any) @ Base ./reduce.jl:85
  │││││││││││││ runtime dispatch detected: Base.reduce_first(add_sum, x::Any)::Any
  ││││││││││││└────────────────────
  ││││││││││││┌ (::Base.BottomRF{typeof(Base.add_sum)})(acc::Any, x::Any) @ Base ./reduce.jl:86
  │││││││││││││ runtime dispatch detected: add_sum(acc::Any, x::Any)::Any
  ││││││││││││└────────────────────
  ││││││││││┌ _foldl_impl(op::Base.MappingRF{var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, Base.BottomRF{typeof(Base.add_sum)}}, init::Int64, itr::UnitRange{Int64}) @ Base ./reduce.jl:62
  │││││││││││ runtime dispatch detected: op::Base.MappingRF{var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, Base.BottomRF{typeof(Base.add_sum)}}(%57::Any, %68::Int64)::Any
  ││││││││││└────────────────────
  │││││││││┌ foldl_impl(op::Base.MappingRF{var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, Base.BottomRF{typeof(Base.add_sum)}}, nt::Int64, itr::UnitRange{Int64}) @ Base ./reduce.jl:49
  ││││││││││┌ reduce_empty_iter(op::Base.MappingRF{var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, Base.BottomRF{typeof(Base.add_sum)}}, itr::UnitRange{Int64}) @ Base ./reduce.jl:383
  │││││││││││┌ reduce_empty_iter(op::Base.MappingRF{var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, Base.BottomRF{typeof(Base.add_sum)}}, itr::UnitRange{Int64}, ::Base.HasEltype) @ Base ./reduce.jl:384
  ││││││││││││┌ reduce_empty(op::Base.MappingRF{var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, Base.BottomRF{typeof(Base.add_sum)}}, ::Type{Int64}) @ Base ./reduce.jl:361
  │││││││││││││ runtime dispatch detected: Base.mapreduce_empty(%1::var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, [quote]::Base.BottomRF{typeof(Base.add_sum)}, ::Int64)
  ││││││││││││└────────────────────
  
ERROR: There was an error during testing

Results, this branch:

julia> JET.maxtypedepth[] = 2;
julia> JET.@test_opt mysum(a[1])
JET-test failed at REPL[8]:1
  Expression: #= REPL[8]:1 =# JET.@test_opt mysum(a[1])
  ═════ 5 possible errors found ═════
  ┌ mysum(x::F49231{…}) @ Main ./REPL[6]:1
  │┌ kwcall(::@NamedTuple{}, ::typeof(sum), f::var"#1#2"{}, a::UnitRange{…}) @ Base ./reducedim.jl:1011
  ││┌ sum(f::var"#1#2"{}, a::UnitRange{…}; dims::Colon, kw::Base.Pairs{…}) @ Base ./reducedim.jl:1011
  │││┌ kwcall(::@NamedTuple{}, ::typeof(Base._sum), f::var"#1#2"{}, a::UnitRange{…}, ::Colon) @ Base ./reducedim.jl:1015
  ││││┌ _sum(f::var"#1#2"{}, a::UnitRange{…}, ::Colon; kw::Base.Pairs{…}) @ Base ./reducedim.jl:1015
  │││││┌ kwcall(::@NamedTuple{}, ::typeof(mapreduce), f::var"#1#2"{}, op::typeof(Base.add_sum), A::UnitRange{…}) @ Base ./reducedim.jl:357
  ││││││┌ mapreduce(f::var"#1#2"{}, op::typeof(Base.add_sum), A::UnitRange{…}; dims::Colon, init::Int64) @ Base ./reducedim.jl:357
  │││││││┌ _mapreduce_dim(f::var"#1#2"{}, op::typeof(Base.add_sum), nt::Int64, A::UnitRange{…}, ::Colon) @ Base ./reducedim.jl:362
  ││││││││┌ mapfoldl_impl(f::var"#1#2"{}, op::typeof(Base.add_sum), nt::Int64, itr::UnitRange{…}) @ Base ./reduce.jl:44
  │││││││││┌ foldl_impl(op::Base.MappingRF{…}, nt::Int64, itr::UnitRange{…}) @ Base ./reduce.jl:48
  ││││││││││┌ _foldl_impl(op::Base.MappingRF{…}, init::Int64, itr::UnitRange{…}) @ Base ./reduce.jl:58
  │││││││││││┌ (::Base.MappingRF{…})(acc::Int64, x::Int64) @ Base ./reduce.jl:100
  ││││││││││││┌ (::Base.BottomRF{…})(acc::Int64, x::Any) @ Base ./reduce.jl:86
  │││││││││││││ runtime dispatch detected: add_sum(acc::Int64, x::Any)::Any
  ││││││││││││└────────────────────
  ││││││││││┌ _foldl_impl(op::Base.MappingRF{…}, init::Int64, itr::UnitRange{…}) @ Base ./reduce.jl:62
  │││││││││││┌ (::Base.MappingRF{…})(acc::Any, x::Int64) @ Base ./reduce.jl:100
  ││││││││││││┌ (::Base.BottomRF{…})(::Base._InitialValue, x::Any) @ Base ./reduce.jl:85
  │││││││││││││ runtime dispatch detected: Base.reduce_first(add_sum, x::Any)::Any
  ││││││││││││└────────────────────
  ││││││││││││┌ (::Base.BottomRF{…})(acc::Any, x::Any) @ Base ./reduce.jl:86
  │││││││││││││ runtime dispatch detected: add_sum(acc::Any, x::Any)::Any
  ││││││││││││└────────────────────
  ││││││││││┌ _foldl_impl(op::Base.MappingRF{…}, init::Int64, itr::UnitRange{…}) @ Base ./reduce.jl:62
  │││││││││││ runtime dispatch detected: op::Base.MappingRF{var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, Base.BottomRF{typeof(Base.add_sum)}}(%57::Any, %68::Int64)::Any
  ││││││││││└────────────────────
  │││││││││┌ foldl_impl(op::Base.MappingRF{…}, nt::Int64, itr::UnitRange{…}) @ Base ./reduce.jl:49
  ││││││││││┌ reduce_empty_iter(op::Base.MappingRF{…}, itr::UnitRange{…}) @ Base ./reduce.jl:383
  │││││││││││┌ reduce_empty_iter(op::Base.MappingRF{…}, itr::UnitRange{…}, ::Base.HasEltype) @ Base ./reduce.jl:384
  ││││││││││││┌ reduce_empty(op::Base.MappingRF{…}, ::Type{…}) @ Base ./reduce.jl:361
  │││││││││││││ runtime dispatch detected: Base.mapreduce_empty(%1::var"#1#2"{F49231{Float64, Float32, Int64, String, AbstractString, 6, Float64}}, [quote]::Base.BottomRF{typeof(Base.add_sum)}, ::Int64)
  ││││││││││││└────────────────────
  
ERROR: There was an error during testing

Closes #616.

src/JET.jl Outdated Show resolved Hide resolved
src/ui/print.jl Outdated Show resolved Hide resolved
src/ui/print.jl Outdated Show resolved Hide resolved
@charleskawczynski charleskawczynski force-pushed the ck/depth_limited_type_printing branch 3 times, most recently from 51d31c1 to 2c7263b Compare January 30, 2024 15:13
@charleskawczynski
Copy link
Contributor Author

I had local changes that I wanted to commit, and I had already amended them, so I just squashed and pushed up all the fixes.

@aviatesk, could you take a second look?

Also, I'm not sure how performant this pattern is:

        buf = IOBuffer()
        _print_signature(buf, a, config; kwargs...)
        write(io, Base_type_depth_limit(buf; maxdepth=2));

. Maybe it's fine? But someone who uses IOBuffers more regularly might recognize a better way.

Copy link

codecov bot commented Feb 1, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 89.46%. Comparing base (93f06e2) to head (8105f34).
Report is 4 commits behind head on master.

❗ Current head 8105f34 differs from pull request most recent head 0f88de4. Consider uploading reports for the commit 0f88de4 to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #601      +/-   ##
==========================================
+ Coverage   89.42%   89.46%   +0.03%     
==========================================
  Files          10       10              
  Lines        3008     3018      +10     
==========================================
+ Hits         2690     2700      +10     
  Misses        318      318              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@aviatesk
Copy link
Owner

aviatesk commented Feb 1, 2024

I'll give another review on this PR next week since I'm quite busy until then.

@aviatesk
Copy link
Owner

Sorry for being late to give a review. I will try to do this weekend or so.

@charleskawczynski
Copy link
Contributor Author

No problem 🙂

@charleskawczynski
Copy link
Contributor Author

Bump 🙂

@charleskawczynski
Copy link
Contributor Author

Is there anything else needed for this PR? @aviatesk?

@charleskawczynski
Copy link
Contributor Author

I’m happy to put more work into it, I’m just not sure what else is needed

@aviatesk
Copy link
Owner

I apologize for the delay in reviewing; I haven't had time to work on JET recently. The changes you've made look great. Thanks so much for contributing.

src/ui/print.jl Outdated Show resolved Hide resolved
@aviatesk
Copy link
Owner

Could you please add a test case to test/ui/test_print.jl, using this commit as a reference: JuliaLang/julia@a43ca05#diff-8d178520d08f2b4258b4bc414729ac2f1f0e65a27c176003f981cbd0b5b72e58? If it's too complicated, just let me know, and I'll take care of it.

@aviatesk
Copy link
Owner

And don't care test failures on 1.11 and nightly-they are known to be broken and we can proceed as far as tests on v1.10 are passing.

@charleskawczynski
Copy link
Contributor Author

charleskawczynski commented Apr 16, 2024

Could you please add a test case to test/ui/test_print.jl, using this commit as a reference: JuliaLang/julia@a43ca05#diff-8d178520d08f2b4258b4bc414729ac2f1f0e65a27c176003f981cbd0b5b72e58? If it's too complicated, just let me know, and I'll take care of it.

I'm happy to add tests for this. The first test I have that seems to work fine is simply:

using Test
import JET
struct F49231{a,b,c,d,e,f,g}
    num::g
end;
bar(x) = rand() > 0.5 ? x : Any[0][1]
mysum(x) = sum(y-> bar(x.num), 1:5; init=0)
@testset "Depth-limited type printing" begin
    f = F49231{Float64,Float32,Int,String,AbstractString,6,Float64}(1)
    Ftype = Tuple{Vector{typeof(f)}}
    result = JET.report_opt(Ftype) do a
        mysum(a[1]) # runtime dispatch !
    end
    buf = IOBuffer()
    show(buf, result)
    s = String(take!(buf))
    @test occursin("F49231{…}", s)
end

However, I'm remembering that one thing I was a bit dissatisfied about with this PR was hard-coding maxdepth = 2. Specifically:

 function print_signature(io, sig::Signature, config; kwargs...)
     for a in sig
-        _print_signature(io, a, config; kwargs...)
+        buf = IOBuffer()
+        _print_signature(buf, a, config; kwargs...)
+        # Let's use maxdepth=2, so that unnamed
+        # functions still show types we recognize.
+        write(io, Base_type_depth_limit(buf; maxdepth=2));
     end
 end

function print_frame_sig(io, frame)
    mi = frame.linfo
    m = mi.def
    if m isa Module
        Base.show_mi(io, mi, #=from_stackframe=#true)
    else
        buf = IOBuffer()
        ioc = IOContext(buf, :backtrace=>true, :limit=>true)
        Base.StackTraces.show_spec_sig(ioc, m, mi.specTypes)
        io = IOContext(io, :backtrace=>true, :limit=>true)
        write(io, Base_type_depth_limit(buf; maxdepth=2));
    end
end

Would you be opposed to adding maxdepth to OptAnalyzer, so that users can pass it in from the jetconfigs kwargs?

@aviatesk
Copy link
Owner

The test case looks nice.

Would you be opposed to adding maxdepth to OptAnalyzer, so that users can pass it in from the jetconfigs kwargs?

No, it would be nice to add the proposed maxdepth configuration to jetconfigs. Implementing a new configuration might be a bit tricky though, so if it feels too complicated, you can leave things as they are for now. We can always make it configurable in a follow-up.

@charleskawczynski
Copy link
Contributor Author

Great 🙂, I pushed up the test. I also made maxdepth to maxtypedepth to avoid confusion with depth. And then I moved maxtypedepth to a const Ref, so that users can interactively change it if they want to set more or less type information. I think this is ready to go, unless you have any more suggestions.

@aviatesk
Copy link
Owner

Got it. I'll be adding a few follow-up commits myself.

@charleskawczynski
Copy link
Contributor Author

Thank you @aviatesk! This will be a quantum leap in quality of life / usability for us. We really look forward to the next release!

src/ui/print.jl Outdated Show resolved Hide resolved
src/ui/print.jl Outdated
print_inference_success::Bool = true,
fullpath::Bool = false,
fullpath::Bool = false,
stacktrace_types_limited::Bool = true,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
stacktrace_types_limited::Bool = true,
stacktrace_types_limit::Int = 2,

What if instead we made this an Int, and then users can customize how deep the type printing goes? We could document that stacktrace_types_limit = -1 or Inf prints all the type information

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That said, I found 2 to be pretty reasonable, but perhaps that's not best for everyone?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked out how type_depth_limit is implemented, and it looks like when maxdepth is nothing, the depth is adjusted dynamically based on the display size. I think this flexible depth might work better in most cases, but what do you think? It might be reasonable to make stacktrace_types_limited::Union{Nothing,Int}=nothing.

Copy link
Contributor Author

@charleskawczynski charleskawczynski Apr 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds good to me, so long it's toggle-able in some way

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, could you make that change if you have time? Otherwise I will work on it tomorrow.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do, thanks!

- recover printing color
- define `stacktrace_types_limited` configuration
@aviatesk aviatesk force-pushed the ck/depth_limited_type_printing branch from 49bbb4f to 6c815d6 Compare April 19, 2024 15:41
@aviatesk
Copy link
Owner

I've made a few updates. Please feel free to add any adjustments. I believe we're nearly ready to merge.

@charleskawczynski
Copy link
Contributor Author

Alright, I pushed the changes, thanks again @aviatesk!

@aviatesk aviatesk merged commit 4d944e3 into aviatesk:master Apr 20, 2024
10 of 22 checks passed
@aviatesk
Copy link
Owner

Thanks a lot @charleskawczynski. This features is planned to be included in the next release.

@charleskawczynski
Copy link
Contributor Author

Thank you so much @aviatesk!

aviatesk added a commit that referenced this pull request Apr 22, 2024
aviatesk added a commit that referenced this pull request Apr 22, 2024
aviatesk added a commit that referenced this pull request Apr 22, 2024
aviatesk added a commit that referenced this pull request Apr 22, 2024
aviatesk added a commit that referenced this pull request Apr 22, 2024
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.

Use depth-limited type printing, from Julia 1.10
2 participants