首页 > 解决方案 > Openmp:在并行内部有一个 MASTER 构造

问题描述

我有一个看起来像这样的 fortran 代码

!$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

当我尝试编译它报告

错误 #7102:在 DO、PARALLEL DO、SECTIONS、PARALLEL SECTIONS 或 SINGLE 指令的动态范围中不允许使用 OpenMP* MASTER 指令。

我不明白。我试图将并行 do 构造修改为此

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

(认为​​它与调度有关)但这并没有改变错误。有谁知道我做错了什么?是不可能在构造master内部使用parallel do还是什么?如果是这样,是否有替代方案?

编辑:

!$OMP SINGLE 
!$OMP END SINGLE

而不是MASTER等效的产生相同的结果...(错误消息)

附言。我只需要其中一个线程来执行progressCallback

标签: fortranopenmp

解决方案


这个问题有点老了,但由于我最近偶然发现了同样的问题,我想分享一个简单的解决方案。这个想法是制定一个 if 子句,它只对其中一个线程评估为 TRUE。这可以通过查询当前线程号轻松实现。通过要求它为零,可以保证该子句对于至少一个线程是正确的:

!$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

推荐阅读