Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Progress bars and OpenMP

Chris_G_2
Beginner
1,787 Views

I have a compute intensive loop parallelized using OpenMP:

!$omp parallel do

do j = 1, nc

call sub1(.....

call sub2(.....

......

.end do

!$omp end parallel do

The software I am developing uses a progress bar, and even with the parallelization the loop can be slow. I would like to insert a progress bar update into it. The progress bar works by checking how long a time has elapsed since it was last updated; if it is greater than a certain limit, then the update occurs via:

call updateProgressBar()

Is there any way of doing this?

 

0 Kudos
4 Replies
jimdempseyatthecove
Honored Contributor III
1,787 Views

The following is a simple hack:

!  TitleProgressBar.f90 
program TitleProgressBar
    use ifwin
    use omp_lib
    implicit none

    logical :: bResult
    integer, parameter :: MaxTitleLength = 200
    character(len=*), parameter :: YourProgramTitle = "TitleProgressBar"
    integer :: i
    integer :: PercentDone, tick
    integer :: N

    bResult = SetConsoleTitle(YourProgramTitle)
    ! ...
    PercentDone = -1    ! -1 to display 0% done bar
    tick = 0
    N=10000
    !$omp parallel do
    do i = 1, N
        call doWork(i)
        !$omp atomic update
        tick = tick + 1
        ! Race condition benign
        if((tick * 100) / N > PercentDone) then
            PercentDone = min((tick * 100) / N, 100)
            bResult = SetConsoleTitle(YourProgramTitle // ' [' // REPEAT('|',PercentDone) // REPEAT(' ', 100-PercentDone) // ']' // CHAR(0))
        endif
    end do
    !$omp end parallel do
    bResult = SetConsoleTitle(YourProgramTitle)
    pause
end program TitleProgressBar

subroutine doWork(i)
    call sleepqq(mod(i,10))
end subroutine doWork

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,787 Views

Try replacing the trailing space with CHAR(249)

Space and '|' are not nearly the same horizontal spacing, CHAR(249) is small center dot and approximates width of '|'

While you can do a Dialog box, this would add a thread. With a significantly more programming you can add a status bar to the console window and place a progress bar there.

Note, display visually stops at 99% (100% is immediately replaced by empty progress). You can change this by replacing the title at a later time (e.g. after you write results to file).

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,787 Views

Also, if you wish, you could code with critical section (introducing delays) or have only one of the threads update (may be jerky but less overhead).

Presumably, if the doWork is moderately long, lines 25 and 26 may complete before a different thread notes the update.

You might consider using:

   integer, volatile :: PercentDone

In the event that your doWork gets inlined, this would prevent PercentDone from being registerized.

By .NOT. using thread-safe update of PercentDone you are trading off a small probability of two (or more) threads updating the progress bar to the same value against the overhead of all threads going through a critical section (or other means of coordination) on every tick update. A bargain I presume.

Jim Dempsey

0 Kudos
Chris_G_2
Beginner
1,787 Views

Thank you Jim - this is just what I need.

 

0 Kudos
Reply