Skip to content

Add render/show_logs to chrome_trace #540

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

Merged
merged 8 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
3 changes: 3 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,19 @@ julia = "1.8"
[extensions]
GraphVizExt = "GraphViz"
GraphVizSimpleExt = "Colors"
JSON3Ext = "JSON3"
PlotsExt = ["DataFrames", "Plots"]

[extras]
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
GraphViz = "f526b714-d49f-11e8-06ff-31ed36ee7ee0"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"

[weakdeps]
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
GraphViz = "f526b714-d49f-11e8-06ff-31ed36ee7ee0"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
1 change: 1 addition & 0 deletions docs/src/logging-visualization.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ converted to a `Val` for dispatch purposes
Built-in rendering support exists for:
- `render_logs(logs, :graphviz)` to generate a graph diagram of executed tasks and their dependencies
- `render_logs(logs, :plots_gantt)` to generate a Gantt chart of task execution across all processors
- `render_logs(logs, :chrome_trace)` to generate a task execution timeline in the chrome-trace format (view in [perfetto web UI](https://ui.perfetto.dev/) or `about:tracing` in a chrome-based browser)

The latter (`MultiEventLog`) allows for continuously rendering logs as they're
generated, permitting real-time visualization of Dagger's operations. This
Expand Down
54 changes: 54 additions & 0 deletions ext/JSON3Ext.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
module JSON3Ext

if isdefined(Base, :get_extension)
using JSON3
else
using ..JSON3
end

using Dagger

function logs_to_chrome_trace(logs::Dict)
execution_logs = Dict{Int,Any}()
Dagger.logs_event_pairs(logs) do w, start_idx, finish_idx
category = logs[w][:core][start_idx].category
if category == :compute
tid = logs[w][:id][start_idx].thunk_id # thunk id
if !haskey(execution_logs, tid)
execution_logs[tid] = Dict{Symbol,Any}()
end
t_start = logs[w][:core][start_idx].timestamp / 1e3 # us
t_stop = logs[w][:core][finish_idx].timestamp / 1e3 # us
proc = logs[w][:id][start_idx].processor
execution_logs[tid][:ts] = t_start
execution_logs[tid][:dur] = t_stop - t_start
execution_logs[tid][:pid] = proc.owner
execution_logs[tid][:tid] = proc.tid # thread id
elseif category == :add_thunk
tid = logs[w][:id][start_idx].thunk_id
if !haskey(execution_logs, tid)
execution_logs[tid] = Dict{Symbol,Any}()
end
f = logs[w][:timeline][start_idx].f
name = "$f"
execution_logs[tid][:name] = name
end
end
events = Vector{Dict{Symbol,Any}}()
for (_, v) in execution_logs
v[:ph] = "X"
v[:cat] = "compute"
push!(events, v)
end
return Dict(:traceEvents => events)
end

function Dagger.render_logs(logs::Dict, ::Val{:chrome_trace})
return JSON3.write(logs_to_chrome_trace(logs))
end

function Dagger.show_logs(io::IO, logs::Dict, ::Val{:chrome_trace})
JSON3.write(io, logs_to_chrome_trace(logs))
end

end # module JSONExt
3 changes: 3 additions & 0 deletions src/Dagger.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ function __init__()
# Gantt chart HTTP server
include("ui/gantt-mux.jl")
end
@reguire JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" begin
include(joinpath(dirname(@__DIR__), "ext", "JSONExt.jl"))
end
end
# TODO: Move to Pkg extensions
@require ProfileSVG="132c30aa-f267-4189-9183-c8a63c7e05e6" begin
Expand Down
5 changes: 4 additions & 1 deletion test/logging.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import TimespanLogging
import TimespanLogging: Timespan, Event, Events, LocalEventLog, MultiEventLog
import Colors, GraphViz, DataFrames, Plots
import Colors, GraphViz, DataFrames, Plots, JSON3

@testset "Logging" begin
@testset "LocalEventLog" begin
Expand Down Expand Up @@ -180,6 +180,9 @@ import Colors, GraphViz, DataFrames, Plots
# PlotsExt
@test Dagger.render_logs(logs, :plots_gantt) !== nothing

# JSON3Ext
@test Dagger.render_logs(logs, :chrome_trace) !== nothing

Dagger.disable_logging!()
end
end
Expand Down