@@ -45,6 +45,29 @@ function BarGlyphs(s::AbstractString)
45
45
end
46
46
return BarGlyphs (glyphs... )
47
47
end
48
+ const defaultglyphs = BarGlyphs (' |' ,' █' , Sys. iswindows () ? ' █' : [' ▏' ,' ▎' ,' ▍' ,' ▌' ,' ▋' ,' ▊' ,' ▉' ],' ' ,' |' ,)
49
+
50
+ # Internal struct for holding common properties and internals for progress meters
51
+ Base. @kwdef mutable struct ProgressCore
52
+ color:: Symbol = :green # color of the meter
53
+ desc:: String = " Progress: " # prefix to the percentage, e.g. "Computing..."
54
+ dt:: Real = Float64 (0.1 ) # minimum time between updates
55
+ enabled:: Bool = true # is the output enabled
56
+ offset:: Int = 0 # position offset of progress bar (default is 0)
57
+ output:: IO = stderr # output stream into which the progress is written
58
+ showspeed:: Bool = false # should the output include average time per iteration
59
+ # internals
60
+ check_iterations:: Int = 1 # number of iterations to check time for
61
+ counter:: Int = 0 # current iteration
62
+ lock:: Threads.ReentrantLock = Threads. ReentrantLock () # lock used when threading detected
63
+ numprintedvalues:: Int = 0 # num values printed below progress in last iteration
64
+ prev_update_count:: Int = 1 # counter at last update
65
+ printed:: Bool = false # true if we have issued at least one status update
66
+ threads_used:: Vector{Int} = Int[] # threads that have used this progress meter
67
+ tinit:: Float64 = time () # time meter was initialized
68
+ tlast:: Float64 = time () # time of last update
69
+ tsecond:: Float64 = time () # ignore the first loop given usually uncharacteristically slow
70
+ end
48
71
49
72
"""
50
73
`prog = Progress(n; dt=0.1, desc="Progress: ", color=:green,
@@ -57,46 +80,37 @@ the current task. Optionally you can disable the progress bar by setting
57
80
"(12.34 ms/it)" to the description by setting `showspeed=true`.
58
81
"""
59
82
mutable struct Progress <: AbstractProgress
60
- n:: Int
61
- reentrantlocker:: Threads.ReentrantLock
62
- dt:: Float64
63
- counter:: Int
64
- tinit:: Float64
65
- tsecond:: Float64 # ignore the first loop given usually uncharacteristically slow
66
- tlast:: Float64
67
- printed:: Bool # true if we have issued at least one status update
68
- desc:: String # prefix to the percentage, e.g. "Computing..."
83
+ n:: Int # total number of iterations
84
+ start:: Int # which iteration number to start from
69
85
barlen:: Union{Int,Nothing} # progress bar size (default is available terminal width)
70
- barglyphs:: BarGlyphs # the characters to be used in the bar
71
- color:: Symbol # default to green
72
- output:: IO # output stream into which the progress is written
73
- offset:: Int # position offset of progress bar (default is 0)
74
- numprintedvalues:: Int # num values printed below progress in last iteration
75
- start:: Int # which iteration number to start from
76
- enabled:: Bool # is the output enabled
77
- showspeed:: Bool # should the output include average time per iteration
78
- check_iterations:: Int
79
- prev_update_count:: Int
80
- threads_used:: Vector{Int}
81
-
82
- function Progress (n:: Integer ;
83
- dt:: Real = 0.1 ,
84
- desc:: AbstractString = " Progress: " ,
85
- color:: Symbol = :green ,
86
- output:: IO = stderr ,
87
- barlen= nothing ,
88
- barglyphs:: BarGlyphs = BarGlyphs (' |' ,' █' , Sys. iswindows () ? ' █' : [' ▏' ,' ▎' ,' ▍' ,' ▌' ,' ▋' ,' ▊' ,' ▉' ],' ' ,' |' ,),
89
- offset:: Integer = 0 ,
90
- start:: Integer = 0 ,
91
- enabled:: Bool = true ,
92
- showspeed:: Bool = false ,
93
- )
86
+ barglyphs:: BarGlyphs # the characters to be used in the bar
87
+ # internals
88
+ core:: ProgressCore
89
+
90
+ function Progress (
91
+ n:: Integer ;
92
+ start:: Integer = 0 ,
93
+ barlen:: Union{Int,Nothing} = nothing ,
94
+ barglyphs:: BarGlyphs = defaultglyphs,
95
+ kwargs... )
94
96
CLEAR_IJULIA[] = clear_ijulia ()
95
- reentrantlocker = Threads. ReentrantLock ()
96
- counter = start
97
- tinit = tsecond = tlast = time ()
98
- printed = false
99
- new (n, reentrantlocker, dt, counter, tinit, tsecond, tlast, printed, desc, barlen, barglyphs, color, output, offset, 0 , start, enabled, showspeed, 1 , 1 , Int[])
97
+ core = ProgressCore (;kwargs... )
98
+ new (n, start, barlen, barglyphs, core)
99
+ end
100
+ end
101
+ # forward common core properties to main types
102
+ function Base. setproperty! (p:: T , name:: Symbol , value) where T<: AbstractProgress
103
+ if hasfield (T, name)
104
+ setfield! (p, name, value)
105
+ else
106
+ setproperty! (p. core, name, value)
107
+ end
108
+ end
109
+ function Base. getproperty (p:: T , name:: Symbol ) where T<: AbstractProgress
110
+ if hasfield (T, name)
111
+ getfield (p, name)
112
+ else
113
+ getproperty (p. core, name)
100
114
end
101
115
end
102
116
@@ -112,39 +126,16 @@ per-iteration average duration like "(12.34 ms/it)" to the description by
112
126
setting `showspeed=true`.
113
127
"""
114
128
mutable struct ProgressThresh{T<: Real } <: AbstractProgress
115
- thresh:: T
116
- reentrantlocker:: Threads.ReentrantLock
117
- dt:: Float64
118
- val:: T
119
- counter:: Int
120
- triggered:: Bool
121
- tinit:: Float64
122
- tlast:: Float64
123
- printed:: Bool # true if we have issued at least one status update
124
- desc:: String # prefix to the percentage, e.g. "Computing..."
125
- color:: Symbol # default to green
126
- output:: IO # output stream into which the progress is written
127
- numprintedvalues:: Int # num values printed below progress in last iteration
128
- offset:: Int # position offset of progress bar (default is 0)
129
- enabled:: Bool # is the output enabled
130
- showspeed:: Bool # should the output include average time per iteration
131
- check_iterations:: Int
132
- prev_update_count:: Int
133
- threads_used:: Vector{Int}
134
-
135
- function ProgressThresh {T} (thresh;
136
- dt:: Real = 0.1 ,
137
- desc:: AbstractString = " Progress: " ,
138
- color:: Symbol = :green ,
139
- output:: IO = stderr ,
140
- offset:: Integer = 0 ,
141
- enabled = true ,
142
- showspeed:: Bool = false ) where T
129
+ thresh:: T # termination threshold
130
+ val:: T # current value
131
+ # internals
132
+ triggered:: Bool # has the threshold been reached?
133
+ core:: ProgressCore # common properties and internals
134
+
135
+ function ProgressThresh {T} (thresh; val:: T = typemax (T), triggered:: Bool = false , kwargs... ) where T
143
136
CLEAR_IJULIA[] = clear_ijulia ()
144
- reentrantlocker = Threads. ReentrantLock ()
145
- tinit = tlast = time ()
146
- printed = false
147
- new {T} (thresh, reentrantlocker, dt, typemax (T), 0 , false , tinit, tlast, printed, desc, color, output, 0 , offset, enabled, showspeed, 1 , 1 , Int[])
137
+ core = ProgressCore (;kwargs... )
138
+ new {T} (thresh, val, triggered, core)
148
139
end
149
140
end
150
141
ProgressThresh (thresh:: Real ; kwargs... ) = ProgressThresh {typeof(thresh)} (thresh; kwargs... )
@@ -163,42 +154,17 @@ setting `showspeed=true`. Instead of displaying a counter, it
163
154
can optionally display a spinning ball by passing `spinner=true`.
164
155
"""
165
156
mutable struct ProgressUnknown <: AbstractProgress
166
- done:: Bool
167
- reentrantlocker:: Threads.ReentrantLock
168
- dt:: Float64
169
- counter:: Int
170
- spincounter:: Int
171
- triggered:: Bool
172
- tinit:: Float64
173
- tlast:: Float64
174
- printed:: Bool # true if we have issued at least one status update
175
- desc:: String # prefix to the percentage, e.g. "Computing..."
176
- color:: Symbol # default to green
157
+ # internals
158
+ done:: Bool # is the task done?
177
159
spinner:: Bool # show a spinner
178
- output:: IO # output stream into which the progress is written
179
- numprintedvalues:: Int # num values printed below progress in last iteration
180
- offset:: Int # position offset of progress bar (default is 0)
181
- enabled:: Bool # is the output enabled
182
- showspeed:: Bool # should the output include average time per iteration
183
- check_iterations:: Int
184
- prev_update_count:: Int
185
- threads_used:: Vector{Int}
186
- end
160
+ spincounter:: Int # counter for spinner
161
+ core:: ProgressCore # common properties and internals
187
162
188
- function ProgressUnknown (;
189
- dt:: Real = 0.1 ,
190
- desc:: AbstractString = " Progress: " ,
191
- color:: Symbol = :green ,
192
- spinner:: Bool = false ,
193
- output:: IO = stderr ,
194
- offset:: Integer = 0 ,
195
- enabled:: Bool = true ,
196
- showspeed:: Bool = false )
197
- CLEAR_IJULIA[] = clear_ijulia ()
198
- reentrantlocker = Threads. ReentrantLock ()
199
- tinit = tlast = time ()
200
- printed = false
201
- ProgressUnknown (false , reentrantlocker, dt, 0 , 0 , false , tinit, tlast, printed, desc, color, spinner, output, 0 , offset, enabled, showspeed, 1 , 1 , Int[])
163
+ function ProgressUnknown (; spinner:: Bool = false , kwargs... )
164
+ CLEAR_IJULIA[] = clear_ijulia ()
165
+ core = ProgressCore (;kwargs... )
166
+ new (false , spinner, 0 , core)
167
+ end
202
168
end
203
169
204
170
# ...length of percentage and ETA string with days is 29 characters, speed string is always 14 extra characters
@@ -239,9 +205,9 @@ function calc_check_iterations(p, t)
239
205
end
240
206
241
207
# update progress display
242
- function updateProgress! (p:: Progress ; showvalues = (),
208
+ function updateProgress! (p:: Progress ; showvalues = (),
243
209
truncate_lines = false , valuecolor = :blue ,
244
- offset:: Integer = p. offset, keep = (offset == 0 ),
210
+ offset:: Integer = p. offset, keep = (offset == 0 ),
245
211
desc:: Union{Nothing,AbstractString} = nothing ,
246
212
ignore_predictor = false , color = p. color, max_steps = p. n)
247
213
! p. enabled && return
@@ -326,9 +292,9 @@ function updateProgress!(p::Progress; showvalues = (),
326
292
return nothing
327
293
end
328
294
329
- function updateProgress! (p:: ProgressThresh ; showvalues = (),
295
+ function updateProgress! (p:: ProgressThresh ; showvalues = (),
330
296
truncate_lines = false , valuecolor = :blue ,
331
- offset:: Integer = p. offset, keep = (offset == 0 ),
297
+ offset:: Integer = p. offset, keep = (offset == 0 ),
332
298
desc = p. desc, ignore_predictor = false ,
333
299
color = p. color, thresh = p. thresh)
334
300
! p. enabled && return
484
450
485
451
function lock_if_threading (f:: Function , p:: AbstractProgress )
486
452
if is_threading (p)
487
- lock (p. reentrantlocker ) do
453
+ lock (p. lock ) do
488
454
f ()
489
455
end
490
456
else
@@ -549,8 +515,8 @@ the message printed and its color.
549
515
550
516
See also `finish!`.
551
517
"""
552
- function cancel (p:: AbstractProgress , msg:: AbstractString = " Aborted before all tasks were completed" ;
553
- color = :red , showvalues = (), truncate_lines = false ,
518
+ function cancel (p:: AbstractProgress , msg:: AbstractString = " Aborted before all tasks were completed" ;
519
+ color = :red , showvalues = (), truncate_lines = false ,
554
520
valuecolor = :blue , offset = p. offset, keep = (offset == 0 ))
555
521
lock_if_threading (p) do
556
522
p. offset = offset
@@ -863,13 +829,13 @@ end
863
829
864
830
@showprogress [desc="Computing..."] pmap(x->x^2, 1:50)
865
831
```
866
- displays progress in performing a computation. You may optionally
867
- supply a custom message to be printed that specifies the computation
832
+ displays progress in performing a computation. You may optionally
833
+ supply a custom message to be printed that specifies the computation
868
834
being performed or other options.
869
835
870
- `@showprogress` works for loops, comprehensions, and `map`-like
836
+ `@showprogress` works for loops, comprehensions, and `map`-like
871
837
functions. These `map`-like functions rely on `ncalls` being defined
872
- and can be checked with `methods(ProgressMeter.ncalls)`. New ones can
838
+ and can be checked with `methods(ProgressMeter.ncalls)`. New ones can
873
839
be added by defining `ProgressMeter.ncalls(::typeof(mapfun), args...) = ...`.
874
840
875
841
`@showprogress` is thread-safe and will work with `@distributed` loops
@@ -891,7 +857,7 @@ function showprogress(args...)
891
857
throw (ArgumentError (" Final argument to @showprogress must be a for loop, comprehension, or a map-like function; got $expr " ))
892
858
end
893
859
894
- if expr. head == :call && expr. args[1 ] == :|>
860
+ if expr. head == :call && expr. args[1 ] == :|>
895
861
# e.g. map(x->x^2) |> sum
896
862
expr. args[2 ] = showprogress (progressargs... , expr. args[2 ])
897
863
return expr
@@ -908,7 +874,7 @@ function showprogress(args...)
908
874
elseif expr. head == :macrocall
909
875
macroname = expr. args[1 ]
910
876
911
- if macroname in (Symbol (" @distributed" ), :(Distributed. @distributed ). args[1 ])
877
+ if macroname in (Symbol (" @distributed" ), :(Distributed. @distributed ). args[1 ])
912
878
# can be changed to `:(Distributed.var"@distributed")` if support for pre-1.3 is dropped
913
879
return showprogressdistributed (args... )
914
880
@@ -991,9 +957,9 @@ function showprogress_loop(expr, progressargs)
991
957
# Transform the first loop assignment
992
958
loopassign = expr. args[outerassignidx] = copy (expr. args[outerassignidx])
993
959
994
- if loopassign. head === :filter
960
+ if loopassign. head === :filter
995
961
# e.g. [x for x=1:10, y=1:10 if x>y]
996
- # y will be wrapped in ProgressWrapper
962
+ # y will be wrapped in ProgressWrapper
997
963
for i in 1 : length (loopassign. args)- 1
998
964
loopassign. args[i] = esc (loopassign. args[i])
999
965
end
@@ -1109,7 +1075,7 @@ to define the length of the `Progress` in `@showprogress` and `progress_map`.
1109
1075
Internally uses one of `ncalls_map`, `ncalls_broadcast(!)` or `ncalls_reduce` depending
1110
1076
on the type of `mapfun`.
1111
1077
1112
- Support for additional functions can be added by defining
1078
+ Support for additional functions can be added by defining
1113
1079
`ProgressMeter.ncalls(::typeof(mapfun), ::Function, args...)`.
1114
1080
"""
1115
1081
ncalls (:: typeof (map), :: Function , args... ) = ncalls_map (args... )
0 commit comments