Erik Thysell
Erik Thysell

Reputation: 1352

Openmp: Have a MASTER construct inside parallel do

I have a fortran code that looks like this

!$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(var1, var2, var3, numberOfCalculationsPerformed)
do ix = 1,nx
  ! Do parallel work
  do iy = 1,ny
    ! Do a lot of work....
    !$OMP ATOMIC
    numberOfCalculationsPerformed = numberOfCalculationsPerformed+1
    !$OMP END ATOMIC
    !$OMP MASTER
    ! Report progress
    call progressCallBack(numberOfCalculationsPerformed/totalNCalculations)
    !$OMP END MASTER
  end do
end do

When I try to compile it reports that

error #7102: An OpenMP* MASTER directive is not permitted in the dynamic extent of a DO, PARALLEL DO, SECTIONS, PARALLEL SECTIONS, or SINGLE directive.

I do not understand this. I have tried to modify the parallel do construct to this

!$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(var1, var2, var3, numberOfCalculationsPerformed), &
!$OMP& SCHEDULE(STATIC)

(in the thought that it had something to do with the scheduling) but that did nothing to change the error. Does anyone know what I am not getting right? Is it just impossible to use master inside a parallel do construct or what? If that is so, are there alternatives?

Edit:

!$OMP SINGLE 
!$OMP END SINGLE

Instead of the MASTER equivalent yields the same result... (error message)

Ps. I only need one of the threads to execute progressCallback.

Upvotes: 0

Views: 394

Answers (1)

Elarion
Elarion

Reputation: 56

The question is a bit old, but since I recently stumbled across the same issue, I wanted to share a simple solution. The idea is to formulate an if-clause which only evaluates to TRUE for one of the threads. This can easily be achieved by querying the current thread number. By requiring it to be zero, the clause is guaranteed to be true for at least one thread:

!$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(var1, var2, var3, numberOfCalculationsPerformed)
do ix = 1,nx
  ! Do parallel work
  do iy = 1,ny
    ! Do a lot of work....
    !$OMP ATOMIC
    numberOfCalculationsPerformed = numberOfCalculationsPerformed+1
    !$OMP END ATOMIC

    if (OMP_GET_THREAD_NUM() == 0) then
        ! Report progress
        call progressCallBack(numberOfCalculationsPerformed/totalNCalculations)
    end if
  end do
end do

Upvotes: 1

Related Questions