From 7e2bbca9f9fac81058f4ed7a2f9b2a087ee5f1e0 Mon Sep 17 00:00:00 2001 From: MarcMush <35898736+MarcMush@users.noreply.github.com> Date: Wed, 28 Feb 2024 10:47:58 +0100 Subject: [PATCH] Support more complex comprehensions (#302) * better comprehensions * allow Distributed.@distributed --- README.md | 4 +- src/ProgressMeter.jl | 269 ++++++++++++++++++++++------------------ test/core.jl | 4 +- test/test.jl | 221 ++++++++++++++++++++------------- test/test_float.jl | 36 +++--- test/test_showvalues.jl | 44 +++---- test/test_threads.jl | 41 +++--- 7 files changed, 343 insertions(+), 276 deletions(-) diff --git a/README.md b/README.md index 850cf09..abe7306 100644 --- a/README.md +++ b/README.md @@ -229,7 +229,7 @@ while true next!(prog) rand(1:2*10^8) == 1 && break end -ProgressMeter.finish!(prog) +finish!(prog) ``` By default, `finish!` changes the spinner to a `βœ“`, but you can @@ -421,7 +421,7 @@ p = Progress(n; enabled = false) for iter in 1:10 x *= 2 sleep(0.5) - ProgressMeter.next!(p) + next!(p) end ``` diff --git a/src/ProgressMeter.jl b/src/ProgressMeter.jl index 8933bc7..7ca7862 100644 --- a/src/ProgressMeter.jl +++ b/src/ProgressMeter.jl @@ -782,10 +782,6 @@ function showprogressdistributed(args...) progressargs = args[1:end-1] expr = Base.remove_linenums!(args[end]) - if expr.head != :macrocall || expr.args[1] != Symbol("@distributed") - throw(ArgumentError("malformed @showprogress @distributed expression")) - end - distargs = filter(x -> !(x isa LineNumberNode), expr.args[2:end]) na = length(distargs) if na == 1 @@ -846,7 +842,7 @@ function showprogressthreads(args...) iters = loop.args[1].args[end] p = gensym() - push!(loop.args[end].args, :(ProgressMeter.next!($p))) + push!(loop.args[end].args, :(next!($p))) quote $(esc(p)) = Progress( @@ -890,146 +886,173 @@ function showprogress(args...) end progressargs = args[1:end-1] expr = args[end] - if expr.head == :macrocall && expr.args[1] == Symbol("@distributed") - return showprogressdistributed(args...) - end - if expr.head == :macrocall && expr.args[1] == :(Threads.var"@threads") - return showprogressthreads(args...) + + if !isa(expr, Expr) + throw(ArgumentError("Final argument to @showprogress must be a for loop, comprehension, or a map-like function; got $expr")) end - orig = expr = copy(expr) - if expr.args[1] == :|> # e.g. map(x->x^2) |> sum + + if expr.head == :call && expr.args[1] == :|> + # e.g. map(x->x^2) |> sum expr.args[2] = showprogress(progressargs..., expr.args[2]) return expr + + elseif expr.head in (:for, :comprehension, :typed_comprehension) + return showprogress_loop(expr, progressargs) + + elseif expr.head == :call + return showprogress_map(expr, progressargs) + + elseif expr.head == :do && expr.args[1].head == :call + return showprogress_map(expr, progressargs) + + elseif expr.head == :macrocall + macroname = expr.args[1] + + if macroname in (Symbol("@distributed"), :(Distributed.@distributed).args[1]) + # can be changed to `:(Distributed.var"@distributed")` if support for pre-1.3 is dropped + return showprogressdistributed(args...) + + elseif macroname in (Symbol("@threads"), :(Threads.@threads).args[1]) + return showprogressthreads(args...) + end end + + throw(ArgumentError("Final argument to @showprogress must be a for loop, comprehension, or a map-like function; got $expr")) +end + +function showprogress_map(expr, progressargs) metersym = gensym("meter") - kind = :invalid # :invalid, :loop, or :map - - if isa(expr, Expr) - if expr.head == :for - outerassignidx = 1 - loopbodyidx = lastindex(expr.args) - kind = :loop - elseif expr.head == :comprehension - outerassignidx = lastindex(expr.args) - loopbodyidx = 1 - kind = :loop - elseif expr.head == :typed_comprehension - outerassignidx = lastindex(expr.args) - loopbodyidx = 2 - kind = :loop - elseif expr.head == :call - kind = :map - elseif expr.head == :do - call = expr.args[1] - if call.head == :call - kind = :map - end - end + + # isolate call to map + if expr.head == :do + call = expr.args[1] + else + call = expr end - if kind == :invalid - throw(ArgumentError("Final argument to @showprogress must be a for loop, comprehension, or a map-like function; got $expr")) - elseif kind == :loop - # As of julia 0.5, a comprehension's "loop" is actually one level deeper in the syntax tree. - if expr.head !== :for - @assert length(expr.args) == loopbodyidx - expr = expr.args[outerassignidx] = copy(expr.args[outerassignidx]) - @assert expr.head === :generator - outerassignidx = lastindex(expr.args) - loopbodyidx = 1 - end + # get args to map to determine progress length + mapargs = collect(Any, filter(call.args[2:end]) do a + return isa(a, Symbol) || isa(a, Number) || !(a.head in (:kw, :parameters)) + end) + if expr.head == :do + insert!(mapargs, 1, identity) # to make args for ncalls line up + end - # Transform the first loop assignment - loopassign = expr.args[outerassignidx] = copy(expr.args[outerassignidx]) - if loopassign.head === :block # this will happen in a for loop with multiple iteration variables - for i in 2:length(loopassign.args) - loopassign.args[i] = esc(loopassign.args[i]) - end - loopassign = loopassign.args[1] = copy(loopassign.args[1]) - end - @assert loopassign.head === :(=) - @assert length(loopassign.args) == 2 - obj = loopassign.args[2] - loopassign.args[1] = esc(loopassign.args[1]) - loopassign.args[2] = :(ProgressWrapper(iterable, $(esc(metersym)))) - - # Transform the loop body break and return statements - if expr.head === :for - expr.args[loopbodyidx] = showprogress_process_expr(expr.args[loopbodyidx], metersym) - end + # change call to progress_map + mapfun = call.args[1] + call.args[1] = :progress_map - # Escape all args except the loop assignment, which was already appropriately escaped. - for i in 1:length(expr.args) - if i != outerassignidx - expr.args[i] = esc(expr.args[i]) - end - end - if orig !== expr - # We have additional escaping to do; this will occur for comprehensions with julia 0.5 or later. - for i in 1:length(orig.args)-1 - orig.args[i] = esc(orig.args[i]) - end - end + # escape args as appropriate + for i in 2:length(call.args) + call.args[i] = esc(call.args[i]) + end + if expr.head == :do + expr.args[2] = esc(expr.args[2]) + end - setup = quote - iterable = $(esc(obj)) - $(esc(metersym)) = Progress(length(iterable), $(showprogress_process_args(progressargs)...)) - end + # create appropriate Progress expression + lenex = :(ncalls($(esc(mapfun)), $(esc.(mapargs)...))) + progex = :(Progress($lenex, $(showprogress_process_args(progressargs)...))) - if expr.head === :for - return quote - $setup - $expr - end - else - # We're dealing with a comprehension - return quote - begin - $setup - rv = $orig - next!($(esc(metersym))) - rv - end - end + # insert progress and mapfun kwargs + push!(call.args, Expr(:kw, :progress, progex)) + push!(call.args, Expr(:kw, :mapfun, esc(mapfun))) + + return expr +end + +function showprogress_loop(expr, progressargs) + metersym = gensym("meter") + orig = expr = copy(expr) + + if expr.head == :for + outerassignidx = 1 + loopbodyidx = lastindex(expr.args) + elseif expr.head == :comprehension + outerassignidx = lastindex(expr.args) + loopbodyidx = 1 + elseif expr.head == :typed_comprehension + outerassignidx = lastindex(expr.args) + loopbodyidx = 2 + end + # As of julia 0.5, a comprehension's "loop" is actually one level deeper in the syntax tree. + if expr.head !== :for + @assert length(expr.args) == loopbodyidx + expr = expr.args[outerassignidx] = copy(expr.args[outerassignidx]) + if expr.head == :flatten + # e.g. [x for x in 1:10 for y in 1:x] + expr = expr.args[1] = copy(expr.args[1]) end - else # kind == :map + @assert expr.head === :generator + outerassignidx = lastindex(expr.args) + loopbodyidx = 1 + end - # isolate call to map - if expr.head == :do - call = expr.args[1] - else - call = expr + # Transform the first loop assignment + loopassign = expr.args[outerassignidx] = copy(expr.args[outerassignidx]) + + if loopassign.head === :filter + # e.g. [x for x=1:10, y=1:10 if x>y] + # y will be wrapped in ProgressWrapper + for i in 1:length(loopassign.args)-1 + loopassign.args[i] = esc(loopassign.args[i]) end + loopassign = loopassign.args[end] = copy(loopassign.args[end]) + end - # get args to map to determine progress length - mapargs = collect(Any, filter(call.args[2:end]) do a - return isa(a, Symbol) || isa(a, Number) || !(a.head in (:kw, :parameters)) - end) - if expr.head == :do - insert!(mapargs, 1, identity) # to make args for ncalls line up + if loopassign.head === :block + # e.g. for x=1:10, y=1:x end + # x will be wrapped in ProgressWrapper + for i in 2:length(loopassign.args) + loopassign.args[i] = esc(loopassign.args[i]) end + loopassign = loopassign.args[1] = copy(loopassign.args[1]) + end + + @assert loopassign.head === :(=) + @assert length(loopassign.args) == 2 + obj = loopassign.args[2] + loopassign.args[1] = esc(loopassign.args[1]) + loopassign.args[2] = :(ProgressWrapper(iterable, $(esc(metersym)))) - # change call to progress_map - mapfun = call.args[1] - call.args[1] = :progress_map + # Transform the loop body break and return statements + if expr.head === :for + expr.args[loopbodyidx] = showprogress_process_expr(expr.args[loopbodyidx], metersym) + end - # escape args as appropriate - for i in 2:length(call.args) - call.args[i] = esc(call.args[i]) + # Escape all args except the loop assignment, which was already appropriately escaped. + for i in 1:length(expr.args) + if i != outerassignidx + expr.args[i] = esc(expr.args[i]) end - if expr.head == :do - expr.args[2] = esc(expr.args[2]) + end + if orig !== expr + # We have additional escaping to do; this will occur for comprehensions with julia 0.5 or later. + for i in 1:length(orig.args)-1 + orig.args[i] = esc(orig.args[i]) end + end - # create appropriate Progress expression - lenex = :(ncalls($(esc(mapfun)), $(esc.(mapargs)...))) - progex = :(Progress($lenex, $(showprogress_process_args(progressargs)...))) - - # insert progress and mapfun kwargs - push!(call.args, Expr(:kw, :progress, progex)) - push!(call.args, Expr(:kw, :mapfun, esc(mapfun))) + setup = quote + iterable = $(esc(obj)) + $(esc(metersym)) = Progress(length(iterable), $(showprogress_process_args(progressargs)...)) + end - return expr + if expr.head === :for + return quote + $setup + $expr + end + else + # We're dealing with a comprehension + return quote + begin + $setup + rv = $orig + finish!($(esc(metersym))) + rv + end + end end end diff --git a/test/core.jl b/test/core.jl index 4636af5..1b82988 100644 --- a/test/core.jl +++ b/test/core.jl @@ -10,8 +10,8 @@ @test ProgressMeter.durationstring(60*60*24*10 - 0.1) == "9 days, 23:59:59" @test ProgressMeter.durationstring(60*60*24*10) == "10.00 days" -@test ProgressMeter.Progress(5, desc="Progress:", offset=Int16(5)).offset == 5 -@test ProgressMeter.ProgressThresh(0.2, desc="Progress:", offset=Int16(5)).offset == 5 +@test Progress(5, desc="Progress:", offset=Int16(5)).offset == 5 +@test ProgressThresh(0.2, desc="Progress:", offset=Int16(5)).offset == 5 # test speed string formatting for ns in [1, 9, 10, 99, 100, 999, 1_000, 9_999, 10_000, 99_000, 100_000, 999_999, 1_000_000, 9_000_000, 10_000_000, 99_999_000, 1_234_567_890, 1_234_567_890 * 10, 1_234_567_890 * 100, 1_234_567_890 * 1_000, 1_234_567_890 * 10_000, 1_234_567_890 * 100_000, 1_234_567_890 * 1_000_000, 1_234_567_890 * 10_000_000] diff --git a/test/test.jl b/test/test.jl index 95951fc..d37ce5b 100644 --- a/test/test.jl +++ b/test/test.jl @@ -3,10 +3,10 @@ using Random: seed! seed!(123) function testfunc(n, dt, tsleep) - p = ProgressMeter.Progress(n; dt=dt) + p = Progress(n; dt=dt) for i = 1:n sleep(tsleep) - ProgressMeter.next!(p) + next!(p) end end println("Testing original interface...") @@ -14,10 +14,10 @@ testfunc(107, 0.01, 0.01) function testfunc2(n, dt, tsleep, desc, barlen) - p = ProgressMeter.Progress(n; dt=dt, desc=desc, barlen=barlen) + p = Progress(n; dt=dt, desc=desc, barlen=barlen) for i = 1:n sleep(tsleep) - ProgressMeter.next!(p) + next!(p) end end println("Testing desc and progress bar") @@ -27,10 +27,10 @@ testfunc2(107, 0.01, 0.01, "", 0) function testfunc3(n, tsleep, desc) - p = ProgressMeter.Progress(n; desc=desc) + p = Progress(n; desc=desc) for i = 1:n sleep(tsleep) - ProgressMeter.next!(p) + next!(p) end end println("Testing tty width...") @@ -42,10 +42,10 @@ testfunc3(107, 0.02, "") function testfunc4() # test "days" format - p = ProgressMeter.Progress(10000000, desc="Test...") + p = Progress(10000000, desc="Test...") for i = 1:105 sleep(0.02) - ProgressMeter.next!(p) + next!(p) end end @@ -53,14 +53,14 @@ println("Testing that not even 1% required...") testfunc4() function testfunc5A(n, dt, tsleep, desc, barlen) - p = ProgressMeter.Progress(n; dt=dt, desc=desc, barlen=barlen) + p = Progress(n; dt=dt, desc=desc, barlen=barlen) for i = 1:round(Int, floor(n/2)) sleep(tsleep) - ProgressMeter.next!(p) + next!(p) end for i = round(Int, ceil(n/2)):n sleep(tsleep) - ProgressMeter.next!(p; color=:red) + next!(p; color=:red) end end @@ -68,13 +68,13 @@ println("\nTesting changing the bar color") testfunc5A(107, 0.01, 0.01, "Computing...", 50) function testfunc5B(n, dt, tsleep, desc, barlen) - p = ProgressMeter.Progress(n; dt=dt, desc=desc, barlen=barlen) + p = Progress(n; dt=dt, desc=desc, barlen=barlen) for i = 1:n sleep(tsleep) - ProgressMeter.next!(p) + next!(p) if i % 10 == 0 stepnum = floor(Int, i/10) + 1 - ProgressMeter.update!(p, desc = "Step $stepnum...") + update!(p, desc = "Step $stepnum...") end end end @@ -84,7 +84,7 @@ testfunc5B(107, 0.01, 0.02, "Step 1...", 50) function testfunc6(n, dt, tsleep) - ProgressMeter.@showprogress dt=dt for i in 1:n + @showprogress dt=dt for i in 1:n if i == div(n, 2) break end @@ -96,7 +96,7 @@ function testfunc6(n, dt, tsleep) end function testfunc6a(n, dt, tsleep) - ProgressMeter.@showprogress dt=dt for i in 1:n, j in 1:n + @showprogress dt=dt for i in 1:n, j in 1:n if i == div(n, 2) break end @@ -111,29 +111,59 @@ println("Testing @showprogress macro on for loop") testfunc6(3000, 0.01, 0.002) testfunc6a(30, 0.01, 0.002) - function testfunc7(n, dt, tsleep) - s = ProgressMeter.@showprogress dt=dt desc="Calculating..." [(sleep(tsleep); z) for z in 1:n] + s = @showprogress dt=dt desc="Calculating..." [(sleep(tsleep); z) for z in 1:n] @test s == [1:n;] end function testfunc7a(n, dt, tsleep) - s = ProgressMeter.@showprogress dt=dt desc="Calculating..." [(sleep(tsleep); z) for z in 1:n, y in 1:n] + s = @showprogress dt=dt desc="Calculating..." [(sleep(tsleep); z) for z in 1:n, y in 1:n] @test s == [z for z in 1:n, y in 1:n] end function testfunc7b(A, dt, tsleep) - s = ProgressMeter.@showprogress dt=dt desc="Calculating..." [(sleep(tsleep); z) for z in A] + s = @showprogress dt=dt desc="Calculating..." [(sleep(tsleep); z) for z in A] @test s == A end +function testfunc7c(tsleep) + s = @showprogress desc="inc should be 10% " [(sleep(tsleep); a+b+c) for a=1:10 for b=1:7 for c=1:3] + @test s == [a+b+c for a=1:10 for b=1:7 for c=1:3] +end + +function testfunc7d(tsleep) + s = @showprogress desc="inc should be 10% " [(sleep(tsleep); a+b+c) for a=1:3,b=1:10 for c=1:a+b] + @test s == [a+b+c for a=1:3,b=1:10 for c=1:a+b] +end + +function testfunc7e(tsleep) + s = @showprogress desc="inc should be 10% " [(sleep(tsleep); a+b) for a=1:29,b=1:10 if b>a] + @test s == [a+b for a=1:29,b=1:10 if b>a] +end + +function testfunc7f(tsleep) + s = @showprogress desc="inc should be 10% " [(sleep(tsleep); a+b) for a=1:10 for b=1:29 if b ]") # Threshold-based progress reports println("Testing threshold-based progress") -prog = ProgressMeter.ProgressThresh(1e-5; desc="Minimizing:") +prog = ProgressThresh(1e-5; desc="Minimizing:") for val in 10 .^ range(2, stop=-6, length=20) - ProgressMeter.update!(prog, val) + update!(prog, val) sleep(0.1) end # issue #166 -@test ProgressMeter.ProgressThresh(1.0f0; desc = "Desc: ") isa ProgressMeter.ProgressThresh{Float32} +@test ProgressThresh(1.0f0; desc = "Desc: ") isa ProgressThresh{Float32} # Threshold-based progress reports with increment=false println("Testing threshold-based progress with increment=false") -prog = ProgressMeter.ProgressThresh(1e-5, desc="Minimizing:") +prog = ProgressThresh(1e-5, desc="Minimizing:") for val in 10 .^ range(2, stop=-6, length=20) - ProgressMeter.update!(prog, val; increment=false) + update!(prog, val; increment=false) @test prog.counter == 0 sleep(0.1) end colors = [:red, :blue, :green] -prog = ProgressMeter.ProgressThresh(1e-5, desc="Minimizing:") +prog = ProgressThresh(1e-5, desc="Minimizing:") for val in 10 .^ range(2, stop=-6, length=20) - ProgressMeter.update!(prog, val; color=rand(colors), increment=false) + update!(prog, val; color=rand(colors), increment=false) @test prog.counter == 0 sleep(0.1) end # ProgressUnknown progress reports println("Testing progress unknown") -prog = ProgressMeter.ProgressUnknown(desc="Reading entry:") +prog = ProgressUnknown(desc="Reading entry:") for _ in 1:10 - ProgressMeter.next!(prog) + next!(prog) sleep(0.1) end -ProgressMeter.finish!(prog) +finish!(prog) -prog = ProgressMeter.ProgressUnknown(desc="Reading entry:") +prog = ProgressUnknown(desc="Reading entry:") for k in 1:2:20 - ProgressMeter.update!(prog, k) + update!(prog, k) sleep(0.1) end colors = [:red, :blue, :green] -prog = ProgressMeter.ProgressUnknown(desc="Reading entry:") +prog = ProgressUnknown(desc="Reading entry:") for k in 1:2:20 - ProgressMeter.update!(prog, k; color=rand(colors)) + update!(prog, k; color=rand(colors)) sleep(0.1) end -ProgressMeter.finish!(prog) +finish!(prog) -prog = ProgressMeter.ProgressUnknown(desc="Reading entry:", spinner=true) +prog = ProgressUnknown(desc="Reading entry:", spinner=true) for _ in 1:10 - ProgressMeter.next!(prog) + next!(prog) sleep(0.1) end -ProgressMeter.finish!(prog) +finish!(prog) -prog = ProgressMeter.ProgressUnknown(desc="Reading entry:", spinner=true) +prog = ProgressUnknown(desc="Reading entry:", spinner=true) for _ in 1:10 - ProgressMeter.next!(prog) + next!(prog) sleep(0.1) end -ProgressMeter.finish!(prog, spinner='βœ—') +finish!(prog, spinner='βœ—') myspinner = ['πŸŒ‘', 'πŸŒ’', 'πŸŒ“', 'πŸŒ”', 'πŸŒ•', 'πŸŒ–', 'πŸŒ—', '🌘'] prog = ProgressUnknown(desc="Custom spinner:", spinner=true) for val in 1:10 - ProgressMeter.next!(prog, spinner=myspinner) + next!(prog, spinner=myspinner) sleep(0.1) end -ProgressMeter.finish!(prog, spinner='🌞') +finish!(prog, spinner='🌞') prog = ProgressUnknown(desc="Custom spinner:", spinner=true) for val in 1:10 - ProgressMeter.next!(prog, spinner="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏") + next!(prog, spinner="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏") sleep(0.1) end -ProgressMeter.finish!(prog) +finish!(prog) println("Testing fractional bars") for front in (['▏','β–Ž','▍','β–Œ','β–‹','β–Š', 'β–‰'], ['▁' ,'β–‚' ,'β–ƒ' ,'β–„' ,'β–…' ,'β–†', 'β–‡'], ['β–‘', 'β–’', 'β–“',]) - p = ProgressMeter.Progress(100, dt=0.01, barglyphs=ProgressMeter.BarGlyphs('|','β–ˆ',front,' ','|'), barlen=10) + p = Progress(100, dt=0.01, barglyphs=BarGlyphs('|','β–ˆ',front,' ','|'), barlen=10) for i in 1:100 - ProgressMeter.next!(p) + next!(p) sleep(0.02) end end function testfunc15(n, dt, tsleep) - result = ProgressMeter.@showprogress dt=dt @distributed (+) for i in 1:n + result = @showprogress dt=dt @distributed (+) for i in 1:n if rand() < 0.7 sleep(tsleep) end @@ -371,7 +407,7 @@ println("Testing @showprogress macro on distributed for loop with reducer") testfunc15(3000, 0.01, 0.001) function testfunc16(n, dt, tsleep) - ProgressMeter.@showprogress dt=dt desc="Description: " @distributed for i in 1:n + @showprogress dt=dt desc="Description: " @distributed for i in 1:n if rand() < 0.7 sleep(tsleep) end @@ -383,7 +419,7 @@ println("Testing @showprogress macro on distributed for loop without reducer") testfunc16(3000, 0.01, 0.001) function testfunc16cb(N, dt, tsleep) - ProgressMeter.@showprogress dt=dt @distributed for i in N + @showprogress dt=dt @distributed for i in N if rand() < 0.7 sleep(tsleep) end @@ -399,6 +435,18 @@ testfunc16cb(1:1000, 0.01, 0.002) println("Testing @showprogress macro on distributed for loop with break") testfunc16cb(1000:2000, 0.01, 0.003) +function testfunc16d(n, dt, tsleep) + @showprogress Distributed.@distributed for i in 1:n + if rand() < 0.7 + sleep(tsleep) + end + i ^ 2 + end +end + +println("Testing @showprogress macro on Distributed.@distributed") +testfunc16d(3000, 0.01, 0.001) + println("testing `@showprogress @distributed` in global scope") @showprogress @distributed for i in 1:10 @@ -406,8 +454,7 @@ println("testing `@showprogress @distributed` in global scope") i^2 end -println("testing `@showprogress @distributed (+)` in global scope") -# https://github.com/timholy/ProgressMeter.jl/issues/243 +println("testing `@showprogress @distributed (+)` in global scope") #243 result = @showprogress @distributed (+) for i in 1:10 sleep(0.1) i^2 @@ -419,10 +466,10 @@ end function testfunc17() n = 30 - p = ProgressMeter.Progress(n, start=15) + p = Progress(n, start=15) for i in 15+1:30 sleep(0.1) - ProgressMeter.next!(p) + next!(p) end end @@ -431,26 +478,26 @@ testfunc17() # speed display option function testfunc18A(n, dt, tsleep; start=15) - p = ProgressMeter.Progress(n; dt=dt, start=start, showspeed=true) + p = Progress(n; dt=dt, start=start, showspeed=true) for i in start+1:start+n sleep(tsleep) - ProgressMeter.next!(p) + next!(p) end end function testfunc18B(n, dt, tsleep) - p = ProgressMeter.ProgressUnknown(; dt=dt, showspeed=true) + p = ProgressUnknown(; dt=dt, showspeed=true) for _ in 1:n sleep(tsleep) - ProgressMeter.next!(p) + next!(p) end - ProgressMeter.finish!(p) + finish!(p) end function testfunc18C() - p = ProgressMeter.ProgressThresh(1e-5; desc="Minimizing:", showspeed=true) + p = ProgressThresh(1e-5; desc="Minimizing:", showspeed=true) for val in 10 .^ range(2, stop=-6, length=20) - ProgressMeter.update!(p, val) + update!(p, val) sleep(0.1) end end @@ -461,9 +508,9 @@ testfunc18B(1_000, 0.01, 0.002) testfunc18C() function testfunc19() - p = ProgressMeter.ProgressThresh(1e-5; desc="Minimizing:", showspeed=true) + p = ProgressThresh(1e-5; desc="Minimizing:", showspeed=true) for val in 10 .^ range(2, stop=-6, length=20) - ProgressMeter.update!(p, val; increment=false) + update!(p, val; increment=false) sleep(0.1) end end diff --git a/test/test_float.jl b/test/test_float.jl index 9908da3..291b3b8 100644 --- a/test/test_float.jl +++ b/test/test_float.jl @@ -1,9 +1,9 @@ println("Testing floating normal progress bar (offset 4)") function testfunc1(n, dt, tsleep, desc, barlen, offset) - p = ProgressMeter.Progress(n; dt=dt, desc=desc, barlen=barlen, offset=offset) + p = Progress(n; dt=dt, desc=desc, barlen=barlen, offset=offset) for i = 1:n sleep(tsleep) - ProgressMeter.next!(p) + next!(p) end print("\n" ^ 5) end @@ -11,13 +11,13 @@ testfunc1(30, 0.1, 0.1, "progress ", 70, 4) println("Testing floating normal progress bars with values and keep (2 levels)") function testfunc2(n, dt, tsleep, desc, barlen) - p1 = ProgressMeter.Progress(n; dt=dt, desc=desc, barlen=barlen, offset=0) - p2 = ProgressMeter.Progress(n; dt=dt, desc=desc, barlen=barlen, offset=5) + p1 = Progress(n; dt=dt, desc=desc, barlen=barlen, offset=0) + p2 = Progress(n; dt=dt, desc=desc, barlen=barlen, offset=5) for i = 1:n sleep(tsleep) - ProgressMeter.next!(p1; showvalues = [(:i, i), + next!(p1; showvalues = [(:i, i), (:constant, "foo"), (:isq, i^2), (:large, 2^i)], keep=false) - ProgressMeter.next!(p2; showvalues = [(:i, i), + next!(p2; showvalues = [(:i, i), (:constant, "foo"), (:isq, i^2), (:large, 2^i)]) end print("\n" ^ 10) @@ -26,12 +26,12 @@ testfunc2(50, 0.2, 0.2, "progress ", 70) println("Testing floating normal progress bars with changing offset") function testfunc3(n, dt, tsleep, desc, barlen) - p1 = ProgressMeter.Progress(n; dt=dt, desc=desc, barlen=barlen, offset=0) - p2 = ProgressMeter.Progress(n; dt=dt, desc=desc, barlen=barlen,offset=1) + p1 = Progress(n; dt=dt, desc=desc, barlen=barlen, offset=0) + p2 = Progress(n; dt=dt, desc=desc, barlen=barlen,offset=1) for i = 1:n sleep(tsleep) - ProgressMeter.next!(p1; showvalues = [(:i, i) for _ in 1:i], keep=false) - ProgressMeter.next!(p2; showvalues = [(:i, i), + next!(p1; showvalues = [(:i, i) for _ in 1:i], keep=false) + next!(p2; showvalues = [(:i, i), (:constant, "foo"), (:isq, i^2), (:large, 2^i)], offset = (p1.offset + p1.numprintedvalues)) end print("\n" ^ (10 + 5)) @@ -40,9 +40,9 @@ testfunc3(10, 0.2, 0.5, "progress ", 70) println("Testing floating thresh progress bar (offset 2)") function testfunc4(thresh, dt, tsleep, desc, offset) - prog = ProgressMeter.ProgressThresh(thresh; dt=dt, desc=desc, offset=offset) + prog = ProgressThresh(thresh; dt=dt, desc=desc, offset=offset) for val in 10 .^ range(2, stop=-6, length=20) - ProgressMeter.update!(prog, val) + update!(prog, val) sleep(tsleep) end print("\n" ^ 3) @@ -51,9 +51,9 @@ testfunc4(1e-5, 0.2, 0.2, "Minimizing: ", 2) println("Testing floating in @showprogress macro (3 levels)") function testfunc5(n, tsleep) - ProgressMeter.@showprogress desc="Level 0 " for i in 1:n - ProgressMeter.@showprogress desc=" Level 1 " offset=1 for i2 in 1:n - ProgressMeter.@showprogress desc=" Level 2 " offset=2 for i3 in 1:n + @showprogress desc="Level 0 " for i in 1:n + @showprogress desc=" Level 1 " offset=1 for i2 in 1:n + @showprogress desc=" Level 2 " offset=2 for i3 in 1:n sleep(tsleep) end end @@ -64,12 +64,12 @@ testfunc5(5, 0.1) println("Testing floating unknown progress bar (offset 2)") function testfunc6(desc, n, tsleep, offset) - p = ProgressMeter.ProgressUnknown(desc=desc, offset=offset) + p = ProgressUnknown(desc=desc, offset=offset) for i = 1:n sleep(tsleep) - ProgressMeter.next!(p) + next!(p) end - ProgressMeter.finish!(p) + finish!(p) print("\n" ^ 3) end testfunc6("Computing... ", 100, 0.02, 2) diff --git a/test/test_showvalues.jl b/test/test_showvalues.jl index 50d80f4..a91416d 100644 --- a/test/test_showvalues.jl +++ b/test/test_showvalues.jl @@ -7,106 +7,106 @@ lazy_no_lazy(values) = (rand() < 0.5) ? values : () -> values println("Testing showvalues with a Dict (2 values)") function testfunc1(n, dt, tsleep, desc, barlen) - p = ProgressMeter.Progress(n; dt=dt, desc=desc, barlen=barlen) + p = Progress(n; dt=dt, desc=desc, barlen=barlen) for i = 1:n sleep(tsleep) values = Dict(:i => i, :halfdone => (i >= n/2)) - ProgressMeter.next!(p; showvalues = lazy_no_lazy(values)) + next!(p; showvalues = lazy_no_lazy(values)) end end testfunc1(50, 1, 0.2, "progress ", 70) println("Testing showvalues with an Array of tuples (4 values)") function testfunc2(n, dt, tsleep, desc, barlen) - p = ProgressMeter.Progress(n; dt=dt, desc=desc, barlen=barlen) + p = Progress(n; dt=dt, desc=desc, barlen=barlen) for i = 1:n sleep(tsleep) values = [(:i, i), (:constant, "foo"), (:isq, i^2), (:large, 2^i)] - ProgressMeter.next!(p; showvalues = lazy_no_lazy(values)) + next!(p; showvalues = lazy_no_lazy(values)) end end testfunc2(30, 1, 0.2, "progress ", 60) println("Testing showvalues when types of names differ (3 values)") function testfunc3(n, dt, tsleep, desc, barlen) - p = ProgressMeter.Progress(n; dt=dt, desc=desc, barlen=barlen) + p = Progress(n; dt=dt, desc=desc, barlen=barlen) for i = 1:n sleep(tsleep) values = [(:i, i*10), ("constant", "foo"), ("foobar", round(i*tsleep, digits=4))] - ProgressMeter.next!(p; showvalues = lazy_no_lazy(values)) + next!(p; showvalues = lazy_no_lazy(values)) end end testfunc3(30, 1, 0.2, "progress ", 70) println("Testing progress with showing values when num values to print changes between iterations") function testfunc4(n, dt, tsleep, desc, barlen) - p = ProgressMeter.Progress(n; dt=dt, desc=desc, barlen=barlen) + p = Progress(n; dt=dt, desc=desc, barlen=barlen) for i = 1:n sleep(tsleep) values_pool = [(:i, i*10), ("constant", "foo"), ("foobar", round(i*tsleep, digits=4))] values = values_pool[randn(3) .< 0.5] - ProgressMeter.next!(p; showvalues = lazy_no_lazy(values)) + next!(p; showvalues = lazy_no_lazy(values)) end end testfunc4(30, 1, 0.2, "opt steps ", 70) println("Testing showvalues with changing number of lines") -prog = ProgressMeter.Progress(50) +prog = Progress(50) for i in 1:50 values = Dict(:left => 100 - i, :message => repeat("0123456789", (i%10 + 1)*15), :final => "this comes after") - ProgressMeter.update!(prog, i; showvalues = lazy_no_lazy(values)) + update!(prog, i; showvalues = lazy_no_lazy(values)) sleep(0.1) end println("Testing showvalues with a different color (1 value)") function testfunc5(n, dt, tsleep, desc, barlen) - p = ProgressMeter.Progress(n; dt=dt, desc=desc, barlen=barlen) + p = Progress(n; dt=dt, desc=desc, barlen=barlen) for i = 1:n sleep(tsleep) values = [(:large, 2^i)] - ProgressMeter.next!(p; showvalues = lazy_no_lazy(values), + next!(p; showvalues = lazy_no_lazy(values), valuecolor = :yellow) end end testfunc5(10, 1, 0.2, "progress ", 40) println("Testing showvalues with threshold-based progress") -prog = ProgressMeter.ProgressThresh(1e-5; desc="Minimizing:") +prog = ProgressThresh(1e-5; desc="Minimizing:") for val in 10 .^ range(2, stop=-6, length=20) values = Dict(:margin => abs(val - 1e-5)) - ProgressMeter.update!(prog, val; showvalues = lazy_no_lazy(values)) + update!(prog, val; showvalues = lazy_no_lazy(values)) sleep(0.1) end println("Testing showvalues with online progress") -prog = ProgressMeter.ProgressUnknown(desc="Entries read:") +prog = ProgressUnknown(desc="Entries read:") for title in ["a", "b", "c", "d", "e"] values = Dict(:title => title) - ProgressMeter.next!(prog; showvalues = lazy_no_lazy(values)) + next!(prog; showvalues = lazy_no_lazy(values)) sleep(0.5) end -ProgressMeter.finish!(prog) +finish!(prog) println("Testing showvalues with early cancel") -prog = ProgressMeter.Progress(100; dt=1, desc="progress: ", barlen=70) +prog = Progress(100; dt=1, desc="progress: ", barlen=70) for i in 1:50 values = Dict(:left => 100 - i) - ProgressMeter.update!(prog, i; showvalues = lazy_no_lazy(values)) + update!(prog, i; showvalues = lazy_no_lazy(values)) sleep(0.1) end -ProgressMeter.cancel(prog) +cancel(prog) println("Testing showvalues with truncate") -prog = ProgressMeter.Progress(50; dt=1, desc="progress: ") +prog = Progress(50; dt=1, desc="progress: ") for i in 1:50 values = Dict(:left => 100 - i, :message => repeat("0123456789", i)) - ProgressMeter.update!(prog, i; + update!(prog, i; showvalues = lazy_no_lazy(values), truncate_lines = true) sleep(0.1) end diff --git a/test/test_threads.jl b/test/test_threads.jl index d1ece79..955c4eb 100644 --- a/test/test_threads.jl +++ b/test/test_threads.jl @@ -6,13 +6,13 @@ n = 20 #per thread threadsUsed = fill(false, threads) vals = ones(n*threads) - p = ProgressMeter.Progress(n*threads) + p = Progress(n*threads) p.threads_used = 1:threads # short-circuit the function `is_threading` because it is racy (#232) Threads.@threads for i = 1:(n*threads) threadsUsed[Threads.threadid()] = true vals[i] = 0 sleep(0.1) - ProgressMeter.next!(p) + next!(p) end @test !any(vals .== 1) #Check that all elements have been iterated @test all(threadsUsed) #Ensure that all threads are used @@ -20,7 +20,7 @@ println("Testing ProgressUnknown() with Threads.@threads across $threads threads") trigger = 100.0 - prog = ProgressMeter.ProgressUnknown(desc="Attempts at exceeding trigger:") + prog = ProgressUnknown(desc="Attempts at exceeding trigger:") prog.threads_used = 1:threads vals = Float64[] threadsUsed = fill(false, threads) @@ -32,9 +32,9 @@ return sum(vals) end if valssum <= trigger - ProgressMeter.next!(prog) + next!(prog) elseif !prog.done - ProgressMeter.finish!(prog) + finish!(prog) break else break @@ -47,7 +47,7 @@ println("Testing ProgressThresh() with Threads.@threads across $threads threads") thresh = 1.0 - prog = ProgressMeter.ProgressThresh(thresh; desc="Minimizing:") + prog = ProgressThresh(thresh; desc="Minimizing:") prog.threads_used = 1:threads vals = fill(300.0, 1) threadsUsed = fill(false, threads) @@ -58,9 +58,9 @@ return sum(vals) end if valssum > thresh - ProgressMeter.update!(prog, valssum) + update!(prog, valssum) else - ProgressMeter.finish!(prog) + finish!(prog) break end sleep(0.1*rand()) @@ -77,7 +77,7 @@ tasks = Vector{Task}(undef, threads) # threadsUsed = fill(false, threads) vals = ones(n*threads) - p = ProgressMeter.Progress(n*threads) + p = Progress(n*threads) p.threads_used = 1:threads for t in 1:threads @@ -85,7 +85,7 @@ # threadsUsed[Threads.threadid()] = true vals[(n*(t-1)) + i] = 0 sleep(0.05 + (rand()*0.1)) - ProgressMeter.next!(p) + next!(p) end end wait.(tasks) @@ -96,19 +96,16 @@ end end - - @static if VERSION >= v"1.3.0-rc1" # the Threads.@threads macro is parsed differently before 1.3 - println("Testing @showprogress on a Threads.@threads for loop") - function test_threaded_for_loop(n, dt, tsleep) - result = zeros(n) - ProgressMeter.@showprogress dt=dt Threads.@threads for i in 1:n - if rand() < 0.7 - sleep(tsleep) - end - result[i] = i ^ 2 + println("Testing @showprogress on a Threads.@threads for loop") + function test_threaded_for_loop(n, dt, tsleep) + result = zeros(n) + @showprogress dt=dt Threads.@threads for i in 1:n + if rand() < 0.7 + sleep(tsleep) end - @test sum(result) == sum(abs2.(1:n)) + result[i] = i ^ 2 end - test_threaded_for_loop(3000, 0.01, 0.001) + @test sum(result) == sum(abs2.(1:n)) end + test_threaded_for_loop(3000, 0.01, 0.001) end