Skip to content

6. Talking while the bar runs ​

march printing checkpoints above the bar and the residual at its end

march now saves its solution every 10 steps, and wants to say so; and it wants to show the residual of every step. A print would not do: the bar line ends with a carriage return, so whatever is printed next overwrites the bar. forbear has two ways to talk while the bar runs:

f90
call bar%initialize(prefix_string='march ', bracket_left_string='[', bracket_right_string=']',  &
                    filled_char_string='#', empty_char_string='.', add_progress_percent=.true., &
                    message_color_fg='cyan', width=30, max_value=real(steps, R8P))
f90
call bar%start
residual = 1._R8P
do step = 1, steps
   call advance
   residual = residual / 2._R8P
   if (mod(step, 10) == 0) then
      write(text, '(A,I0,A)') 'step ', step, ': solution saved'
      call bar%write(trim(text))                            ! a line above the bar
   endif
   write(text, '(A,ES9.2)') 'residual', residual
   call bar%update(current=real(step, R8P), message=trim(text)) ! the end of the bar line
enddo

While running:

$ march
step 10: solution saved
step 20: solution saved
march [##############................]  46% residual 1.19E-07

At the end:

$ march
step 10: solution saved
step 20: solution saved
step 30: solution saved
step 40: solution saved
step 50: solution saved
march [##############################] 100% residual 8.88E-16
  • bar%write(text) prints a line above the bar: it clears the bar line, writes the text there, and draws the bar again on the line below. The lines scroll up, the bar stays at the bottom. When the bar is not running (before start, after 100%), or in a log, write just prints the line.
  • update(current, message=text) shows the text at the end of the bar line, in the colours of message_color_fg, message_color_bg and message_style, until the next message. A shorter message leaves nothing of the longer one: every drawing erases the rest of its line.

write writes to the unit of the bar. To keep the results of a program apart from its bar, send the bar to standard error with output_unit=error_unit (see The bar on standard error).

Output you do not control ​

march suspending its bar while a library prints

write works for the lines march prints itself. Now march saves its solution through a library, which prints on its own, with print: those lines would be drawn over the bar. suspend and resume let the library have the terminal for a moment:

f90
call bar%start
do step = 1, steps
   call advance
   call bar%update(current=real(step, R8P))
   if (mod(step, 20) == 0) then
      call bar%suspend           ! the bar leaves the terminal...
      call save_solution(step)   ! ...to a library that prints on its own...
      call bar%resume            ! ...and comes back below its lines
   endif
enddo

While running, after the first save:

$ march
io_library: writing solution_0020.h5
io_library: done, 2.1 MB
march [##############................]  48%

At the end:

$ march
io_library: writing solution_0020.h5
io_library: done, 2.1 MB
io_library: writing solution_0040.h5
io_library: done, 2.1 MB
march [##############################] 100%
  • bar%suspend clears the bar line and shows the cursor at its start: what the library prints starts there, as if there was no bar.
  • bar%resume draws the bar again, below those lines, with the last update. Updates made in between are recorded, not drawn (a long phase of the library may update the bar too).
  • The library is any code: a solver, an I/O layer, the MPI runtime printing a warning. A program that cannot tell when such output comes should suspend the bar around every call that may print.

How often the bar is drawn ​

A bar is not drawn at every update: at most once every min_interval seconds (0.1 by default, ten times a second), and always at 0% and 100%. A loop of a million fast iterations therefore spends its time in the loop, not in its bar; a loop of slow steps is drawn at every step. frequency=f draws only when the progress enters a new multiple of f%, for a bar that should move in coarse steps. A message passed to an update that is not drawn is shown at the next drawing.

What you learned

write for lines above the bar, message for the end of the bar line, suspend and resume around output you do not control; min_interval and frequency. Reference: The bar object, Behaviour and limitations.

Next: 7. Nested loops.

Released under the GPL v3, BSD 2-Clause, BSD 3-Clause or MIT License.