Skip to content

Commit 58af704

Browse files
authored
Merge pull request #153 from tkf/ProgressLogging
Add progress logging based on ProgressLogging.jl spec
2 parents 21da887 + ca5d00d commit 58af704

File tree

3 files changed

+100
-22
lines changed

3 files changed

+100
-22
lines changed

Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ version = "0.4.3"
44

55
[deps]
66
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
7+
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
78
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
89
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
10+
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
911

1012
[compat]
1113
julia = "≥ 0.7.0"

src/BenchmarkTools.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ module BenchmarkTools
33
using JSON
44
using Base.Iterators
55

6+
using Logging: @logmsg, LogLevel
67
using Statistics
8+
using UUIDs: uuid4
79
using Printf
810

911

src/execution.jl

Lines changed: 96 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,54 @@ end
3232
run_result(b::Benchmark, p::Parameters = b.params; kwargs...) = Base.invokelatest(_run, b, p; kwargs...)
3333
lineartrial(b::Benchmark, p::Parameters = b.params; kwargs...) = Base.invokelatest(_lineartrial, b, p; kwargs...)
3434

35+
##############################
36+
# progress logging utilities #
37+
##############################
38+
39+
# As used in ProgressLogging.jl
40+
# https://github.com/JunoLab/ProgressLogging.jl/blob/v0.1.0/src/ProgressLogging.jl#L11
41+
const ProgressLevel = LogLevel(-1)
42+
43+
"""
44+
_withprogress(
45+
name::AbstractString,
46+
group::BenchmarkGroup;
47+
kwargs...,
48+
) do progressid, nleaves, ndone
49+
...
50+
end
51+
52+
Execute do block with following arguments:
53+
54+
* `progressid`: logging ID to be used for `@logmsg`.
55+
* `nleaves`: total number of benchmarks counted at the root benchmark group.
56+
* `ndone`: number of completed benchmarks
57+
58+
They are either extracted from `kwargs` (for sub-groups) or newly created
59+
(for root benchmark group).
60+
"""
61+
function _withprogress(
62+
f,
63+
name::AbstractString,
64+
group::BenchmarkGroup;
65+
progressid = nothing,
66+
nleaves = NaN,
67+
ndone = NaN,
68+
_...,
69+
)
70+
if progressid !== nothing
71+
return f(progressid, nleaves, ndone)
72+
end
73+
progressid = uuid4()
74+
nleaves = length(leaves(group))
75+
@logmsg(ProgressLevel, name, progress = NaN, _id = progressid)
76+
try
77+
return f(progressid, nleaves, 0)
78+
finally
79+
@logmsg(ProgressLevel, name, progress = "done", _id = progressid)
80+
end
81+
end
82+
3583
#############
3684
# execution #
3785
#############
@@ -43,21 +91,35 @@ lineartrial(b::Benchmark, p::Parameters = b.params; kwargs...) = Base.invokelate
4391
function sample end
4492
function _run end
4593

46-
Base.run(b::Benchmark, p::Parameters = b.params; kwargs...) = run_result(b, p; kwargs...)[1]
47-
48-
function Base.run(group::BenchmarkGroup, args...; verbose::Bool = false, pad = "", kwargs...)
49-
result = similar(group)
50-
gcscrub() # run GC before running group, even if individual benchmarks don't manually GC
51-
i = 1
52-
for id in keys(group)
53-
verbose && println(pad, "($(i)/$(length(group))) benchmarking ", repr(id), "...")
54-
took_seconds = @elapsed begin
55-
result[id] = run(group[id], args...; verbose = verbose, pad = pad*" ", kwargs...)
94+
Base.run(b::Benchmark, p::Parameters = b.params; progressid=nothing, nleaves=NaN, ndone=NaN, kwargs...) =
95+
run_result(b, p; kwargs...)[1]
96+
97+
Base.run(group::BenchmarkGroup, args...; verbose::Bool = false, pad = "", kwargs...) =
98+
_withprogress("Benchmarking", group; kwargs...) do progressid, nleaves, ndone
99+
result = similar(group)
100+
gcscrub() # run GC before running group, even if individual benchmarks don't manually GC
101+
i = 1
102+
for id in keys(group)
103+
@logmsg(ProgressLevel, "Benchmarking", progress = ndone / nleaves, _id = progressid)
104+
verbose &&
105+
println(pad, "($(i)/$(length(group))) benchmarking ", repr(id), "...")
106+
took_seconds = @elapsed begin
107+
result[id] = run(
108+
group[id],
109+
args...;
110+
verbose = verbose,
111+
pad = pad * " ",
112+
kwargs...,
113+
progressid = progressid,
114+
nleaves = nleaves,
115+
ndone = ndone,
116+
)
117+
end
118+
ndone += group[id] isa BenchmarkGroup ? length(leaves(group[id])) : 1
119+
verbose && (println(pad, "done (took ", took_seconds, " seconds)"); i += 1)
56120
end
57-
verbose && (println(pad, "done (took ", took_seconds, " seconds)"); i += 1)
121+
return result
58122
end
59-
return result
60-
end
61123

62124
function _lineartrial(b::Benchmark, p::Parameters = b.params; maxevals = RESOLUTION, kwargs...)
63125
params = Parameters(p; kwargs...)
@@ -118,18 +180,30 @@ for i in 1:8 (EVALS[((i*1000)+1):((i+1)*1000)] .= 11 - i) end # linearl
118180

119181
guessevals(t) = t <= length(EVALS) ? EVALS[t] : 1
120182

121-
function tune!(group::BenchmarkGroup; verbose::Bool = false, pad = "", kwargs...)
122-
gcscrub() # run GC before running group, even if individual benchmarks don't manually GC
123-
i = 1
124-
for id in keys(group)
125-
verbose && println(pad, "($(i)/$(length(group))) tuning ", repr(id), "...")
126-
took_seconds = @elapsed tune!(group[id]; verbose = verbose, pad = pad*" ", kwargs...)
127-
verbose && (println(pad, "done (took ", took_seconds, " seconds)"); i += 1)
183+
tune!(group::BenchmarkGroup; verbose::Bool = false, pad = "", kwargs...) =
184+
_withprogress("Tuning", group; kwargs...) do progressid, nleaves, ndone
185+
gcscrub() # run GC before running group, even if individual benchmarks don't manually GC
186+
i = 1
187+
for id in keys(group)
188+
@logmsg(ProgressLevel, "Tuning", progress = ndone / nleaves, _id = progressid)
189+
verbose && println(pad, "($(i)/$(length(group))) tuning ", repr(id), "...")
190+
took_seconds = @elapsed tune!(
191+
group[id];
192+
verbose = verbose,
193+
pad = pad * " ",
194+
kwargs...,
195+
progressid = progressid,
196+
nleaves = nleaves,
197+
ndone = ndone,
198+
)
199+
ndone += group[id] isa BenchmarkGroup ? length(leaves(group[id])) : 1
200+
verbose && (println(pad, "done (took ", took_seconds, " seconds)"); i += 1)
201+
end
202+
return group
128203
end
129-
return group
130-
end
131204

132205
function tune!(b::Benchmark, p::Parameters = b.params;
206+
progressid=nothing, nleaves=NaN, ndone=NaN, # ignored
133207
verbose::Bool = false, pad = "", kwargs...)
134208
warmup(b, verbose = false)
135209
estimate = ceil(Int, minimum(lineartrial(b, p; kwargs...)))

0 commit comments

Comments
 (0)