Skip to content

Commit

Permalink
Merge branch 'master' into ib/threads
Browse files Browse the repository at this point in the history
  • Loading branch information
IanButterworth authored Oct 30, 2021
2 parents aeea375 + 28f3665 commit d5e1b37
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 18 deletions.
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "ProfileView"
uuid = "c46f51b8-102a-5cf2-8d2c-8597cb0e0da7"
author = ["Tim Holy <tim.holy@gmail.com>"]
version = "0.6.10"
version = "0.6.11"

[deps]
Cairo = "159f3aea-2a34-519c-b102-8c37f9878175"
Expand All @@ -13,6 +13,7 @@ Gtk = "4c0ca9eb-093a-5379-98c5-f87ac0bbbf44"
GtkReactive = "27996c0f-39cd-5cc1-a27a-05f136f946b6"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953"
MethodAnalysis = "85b6ec6f-f7df-4429-9514-a64bcd9ee824"
Profile = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79"
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

Expand All @@ -25,6 +26,7 @@ Graphics = "0.4, 1"
Gtk = "0.18, 1"
GtkReactive = "0.7, 1"
IntervalSets = "0.2, 0.3, 0.4, 0.5"
MethodAnalysis = "0.4"
julia = "1"

[extras]
Expand Down
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

# Introduction

This package contains tools for visualizing profiling data collected
This package contains tools for visualizing and interacting with profiling data collected
with [Julia's][Julia] built-in sampling
[profiler][Profiling]. It
can be helpful for getting a big-picture overview of the major
Expand All @@ -19,6 +19,14 @@ This type of plot is known as a [flame
graph](https://github.com/brendangregg/FlameGraph).
The main logic is handled by the [FlameGraphs][FlameGraphs] package; this package is just a visualization front-end.

Compared to other flamegraph viewers, ProfileView adds interactivity features, such as:

- zoom, pan for exploring large flamegraphs
- right-clicking to take you to the source code for a particular statement
- analyzing inference problems via `code_warntype` for specific, user-selected calls

These features are described in detail below.

## Installation

Within Julia, use the [package manager][pkg]:
Expand All @@ -27,7 +35,7 @@ using Pkg
Pkg.add("ProfileView")
```

## Usage and visual interpretation
## Tutorial: usage and visual interpretation

To demonstrate ProfileView, first we have to collect some profiling
data. Here's a simple test function for demonstration:
Expand Down Expand Up @@ -111,6 +119,15 @@ from the absence of pastel-colored bars above much of the red, we
might guess that this makes a substantial
contribution to its total run time.

To determine the nature of the inference problem(s) in a red bar, left-click on it
and then enter

```julia
julia> warntype_last()
```

at the REPL. You'll see the result of Julia's `code_warntype` for that particular call.

## GUI features

### Gtk Interface
Expand Down Expand Up @@ -140,6 +157,13 @@ contribution to its total run time.
window, which you can populate with saved data by clicking on the
"open" icon.

- After clicking on a bar, you can type `warntype_last` and see the
result of `code_warntype` for the call represented by that bar.

- `ProfileView.view(windowname="method1")` allows you to name your window,
which can help avoid confusion when opening several ProfileView windows
simultaneously.

**NOTE**: ProfileView does not support the old JLD-based `*.jlprof` files anymore.
Use the format provided by FlameGraphs v0.2 and higher.

Expand Down
19 changes: 15 additions & 4 deletions src/ProfileView.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ end
using Profile
using FlameGraphs
using Base.StackTraces: StackFrame
using MethodAnalysis
using InteractiveUtils
using Gtk.ShortNames, GtkReactive, Colors, FileIO, IntervalSets
import Cairo
Expand All @@ -15,10 +16,20 @@ using Graphics
using FlameGraphs: Node, NodeData
using Gtk.GConstants.GdkModifierType: SHIFT, CONTROL, MOD1

export @profview
export @profview, warntype_last

const clicked = Ref{Any}(nothing) # for getting access to the clicked bar

"""
warntype_last()
warntype_last(io::IO; kwargs...)
Show `code_warntype` for the most recently-clicked bar.
Optionally direct output to stream `io`. Keyword arguments are passed to `code_warntype`.
"""
warntype_last(io::IO=stdout; kwargs...) = code_warntype(io, call_type(ProfileView.clicked[].linfo.specTypes)...; kwargs...)

svgwrite(args...; kwargs...) = error("SVG support has moved to the ProfileSVG package")

mutable struct ZoomCanvas
Expand Down Expand Up @@ -54,7 +65,7 @@ end
const window_wrefs = WeakKeyDict{Gtk.GtkWindowLeaf,Nothing}()

"""
ProfileView.view([fcolor], data=Profile.fetch(); lidict=nothing, C=false, recur=:off, fontsize=14, kwargs...)
ProfileView.view([fcolor], data=Profile.fetch(); lidict=nothing, C=false, recur=:off, fontsize=14, windowname="Profile", kwargs...)
View profiling results. `data` and `lidict` must be a matched pair from `Profile.retrieve()`.
You have several options to control the output, of which the major ones are:
Expand Down Expand Up @@ -94,10 +105,10 @@ view(::Nothing; kwargs...) = view(FlameGraphs.default_colors, Node(NodeData(Stac
function view(g::Node{NodeData}; kwargs...)
view(FlameGraphs.default_colors, g; kwargs...)
end
function view(fcolor, gdict::Dict{Symbol,Node{NodeData}}; data=nothing, lidict=nothing, kwargs...)

function view(fcolor, gdict::Dict{Symbol,Node{NodeData}}; data=nothing, windowname="Profile", lidict=nothing, kwargs...)
# Display in a window
win = Window("Profile", 800, 600)
win = Window(windowname, 800, 600)

tb = Toolbar()
tb_open = ToolButton("gtk-open")
Expand Down
29 changes: 18 additions & 11 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using ProfileView
using Test

function profile_test(n)
for i = 1:n
Expand All @@ -12,13 +13,6 @@ function profile_test(n)
end
end

function profile_simple_test(n)
for i = 1:n
A = randn(100,100,20)
m = max(A)
end
end

unstable(x) = x > 0.5 ? true : 0.0

function profile_unstable_test(m, n)
Expand All @@ -33,6 +27,8 @@ function profile_unstable_test(m, n)
s, s2
end

# These tests only ensure that code runs, and does not check the "output"

profile_test(1)
@profview profile_test(10)

Expand All @@ -43,12 +39,10 @@ Profile.clear()
ProfileView.view()
ProfileView.view(C=true)
ProfileView.view(fontsize=18)
ProfileView.view(windowname="ProfileWindow")

Profile.clear()
@profile profile_unstable_test(1, 1)
ProfileView.view(ProfileView.FlameGraphs.StackFrameCategory())

Profile.clear()
profile_unstable_test(1, 1)
@profile profile_unstable_test(10, 10^6)
ProfileView.view()

Expand All @@ -59,3 +53,16 @@ ProfileView.view(data, lidict=lidict)


ProfileView.closeall()

# Test `warntype_last`
function add2(x)
y = x[1] + x[2]
return y, backtrace()
end
_, bt = add2(Any[1,2])
st = stacktrace(bt)
ProfileView.clicked[] = st[1]
io = IOBuffer()
warntype_last(io)
str = String(take!(io))
@test occursin("Base.getindex(x, 1)::ANY", str)

0 comments on commit d5e1b37

Please sign in to comment.