Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/SnoopCompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ end

if isdefined(SnoopCompileCore, Symbol("@snoopi_deep"))
include("parcel_snoopi_deep.jl")
export @snoopi_deep, flamegraph, flatten_times, accumulate_by_source, runtime_inferencetime
export @snoopi_deep, InclusiveTiming, flamegraph, flatten_times, accumulate_by_source, runtime_inferencetime
export inference_triggers, callerinstance, callingframe
end

Expand Down
55 changes: 28 additions & 27 deletions src/parcel_snoopi_deep.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,31 @@ struct InclusiveTiming
children::Vector{InclusiveTiming}
end

"""
tinc = InclusiveTiming(t::Core.Compiler.Timings.Timing)

Calculate times for inference for a node and all its children. `tinc.inclusive_time` records this time for
node `tinc`; `tinc.children` gives you access to the children of this node.
"""
function InclusiveTiming(t::Timing)
child_times = InclusiveTiming[
InclusiveTiming(child)
for child in t.children
]
incl_time = t.time + sum(inclusive_time, child_times; init=UInt64(0))
return InclusiveTiming(t.mi_info, incl_time, t.start_time, child_times)
end

Core.MethodInstance(it::InclusiveTiming) = MethodInstance(it.mi_info)
Base.Method(it::InclusiveTiming) = Method(it.mi_info)

inclusive_time(t::InclusiveTiming) = t.inclusive_time

floattime(t::Timing) = t.time / 1e9
floattime(it::InclusiveTiming) = it.inclusive_time / 1e9

Base.show(io::IO, t::InclusiveTiming) = print(io, "InclusiveTiming: ", t.inclusive_time/10^9, " for ", MethodInstance(t), " with ", length(t.children), " direct children")

"""
flatten_times(timing::Core.Compiler.Timings.Timing; tmin_secs = 0.0)

Expand All @@ -55,8 +77,6 @@ function flatten_times(timing::Union{Timing,InclusiveTiming}; tmin_secs = 0.0)
return sort(out; by=first)
end

floattime(t::Timing) = t.time / 1e9
floattime(it::InclusiveTiming) = it.inclusive_time / 1e9

"""
accumulate_by_source(pairs; tmin_secs = 0.0)
Expand Down Expand Up @@ -101,25 +121,6 @@ end

accumulate_by_source(pairs::Vector{Pair{Float64,InferenceFrameInfo}}; kwargs...) = accumulate_by_source(Method, pairs; kwargs...)

Base.show(io::IO, t::InclusiveTiming) = print(io, "InclusiveTiming: ", t.inclusive_time/10^9, " for ", MethodInstance(t), " with ", length(t.children), " direct children")

inclusive_time(t::InclusiveTiming) = t.inclusive_time

"""
tinc = SnoopCompile.build_inclusive_times(t::Core.Compiler.Timings.Timing)

Calculate times for inference for a node and all its children. `tinc.inclusive_time` records this time for
node `tinc`; `tinc.children` gives you access to the children of this node.
"""
function build_inclusive_times(t::Timing)
child_times = InclusiveTiming[
build_inclusive_times(child)
for child in t.children
]
incl_time = t.time + sum(inclusive_time, child_times; init=UInt64(0))
return InclusiveTiming(t.mi_info, incl_time, t.start_time, child_times)
end

## parcel and supporting infrastructure

function isprecompilable(mi::MethodInstance; excluded_modules=Set([Main::Module]))
Expand Down Expand Up @@ -174,7 +175,7 @@ function precompilable_roots!(pc, t::InclusiveTiming, tthresh; excluded_modules=
return pc
end

precompilable_roots(t::Timing, tthresh; kwargs...) = precompilable_roots(build_inclusive_times(t), tthresh; kwargs...)
precompilable_roots(t::Timing, tthresh; kwargs...) = precompilable_roots(InclusiveTiming(t), tthresh; kwargs...)
function precompilable_roots(t::InclusiveTiming, tthresh; kwargs...)
pcs = [precompilable_roots!(Precompiles(it), it, tthresh; kwargs...) for it in t.children if t.inclusive_time >= tthresh]
t_grand_total = sum(inclusive_time, t.children)
Expand Down Expand Up @@ -205,7 +206,7 @@ function parcel(t::InclusiveTiming; tmin=0.0, kwargs...)
tthresh = round(UInt64, tmin * 10^9)
parcel(precompilable_roots(t, tthresh; kwargs...))
end
parcel(t::Timing; kwargs...) = parcel(build_inclusive_times(t); kwargs...)
parcel(t::Timing; kwargs...) = parcel(InclusiveTiming(t); kwargs...)

### write

Expand Down Expand Up @@ -415,7 +416,7 @@ function next_julia_frame(bt, idx)
end

"""
itrigs = inference_triggers(t::Timing, [tinc::InclusiveTiming=build_inclusive_times(t)]; exclude_toplevel=true)
itrigs = inference_triggers(t::Timing, [tinc::InclusiveTiming=InclusiveTiming(t)]; exclude_toplevel=true)

Collect the "triggers" of inference, each a fresh entry into inference via a call dispatched at runtime.
All the entries in `itrigs` are previously uninferred, or are freshly-inferred for specific constant inputs.
Expand Down Expand Up @@ -651,7 +652,7 @@ end

"""
flamegraph(t::Core.Compiler.Timings.Timing; tmin_secs=0.0)
flamegraph(t::SnoopCompile.InclusiveTiming; tmin_secs=0.0)
flamegraph(t::InclusiveTiming; tmin_secs=0.0)

Convert the call tree of inference timings returned from `@snoopi_deep` into a FlameGraph.
Returns a FlameGraphs.FlameGraph structure that represents the timing trace recorded for
Expand Down Expand Up @@ -679,11 +680,11 @@ Node(FlameGraphs.NodeData(ROOT() at typeinfer.jl:70, 0x00, 0:15355670))
NOTE: This function must touch every frame in the provided `Timing` to build inclusive
timing information (`InclusiveTiming`). If you have a very large profile, and you plan to
call this function multiple times (say with different values for `tmin_secs`), you can save
some intermediate time by first calling [`SnoopCompile.build_inclusive_times(t)`](@ref), only once,
some intermediate time by first calling [`InclusiveTiming(t)`](@ref), only once,
and then passing in the `InclusiveTiming` object for all subsequent calls.
"""
function FlameGraphs.flamegraph(t::Timing; tmin_secs = 0.0)
it = build_inclusive_times(t)
it = InclusiveTiming(t)
flamegraph(it; tmin_secs=tmin_secs)
end

Expand Down
2 changes: 1 addition & 1 deletion test/snoopi_deep.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ using AbstractTrees # For FlameGraphs tests
longest_method_time = timesm[end][1]
@test length(accumulate_by_source(times; tmin_secs=longest_method_time)) == 1

itiming = SnoopCompile.build_inclusive_times(timing)
itiming = InclusiveTiming(timing)
@test SnoopCompile.isROOT(Core.MethodInstance(itiming))
@test SnoopCompile.isROOT(Method(itiming))
itimes = flatten_times(itiming)
Expand Down