do-cycle-exit 中的 Coarray 死锁

Coarray deadlock in do-cycle-exit

下面的Coarray代码出现了一个奇怪的现象

program strange

implicit none
integer :: counter = 0
logical :: co_missionAccomplished[*]

co_missionAccomplished = .false.

sync all

do
  if (this_image()==1) then
    counter = counter+1
    if (counter==2) co_missionAccomplished = .true.
    sync images(*)
  else
    sync images(1)
  end if
  if (co_missionAccomplished[1]) exit
  cycle
end do

write(*,*) "missionAccomplished on image ", this_image()

end program strange

这个程序永远不会结束,因为循环内任何超过 1 的计数器阈值似乎都存在死锁。该代码使用 Intel Fortran 2018 Windows OS 编译,具有以下标志:

ifort /debug /Qcoarray=shared /standard-semantics /traceback /gen-interfaces /check /fpe:0 normal.f90 -o run.exe

同样的代码,使用 DO WHILE 构造,也出现同样的现象:

program strange

implicit none
integer :: counter = 0
logical :: co_missionAccomplished[*]

co_missionAccomplished = .true.

sync all

do while(co_missionAccomplished[1])
  if (this_image()==1) then
    counter = counter+1
    if (counter==2) co_missionAccomplished = .false.
    sync images(*)
  else
    sync images(1)
  end if
end do

write(*,*) "missionAccomplished on image ", this_image()

end program strange

这现在看起来太微不足道了,不可能成为编译器错误,所以我可能遗漏了一些关于并行 do 循环的重要信息。感谢您的帮助。

更新:

在上面的DO-CYCLE-EXIT 示例程序中的CYCLE 语句之前添加SYNC ALL 语句解决了死锁。此外,在 DO WHILE 语句之后的 SYNC ALL 语句作为块的第一行解决了死锁。显然,在上述任何一种情况下,所有图像都必须同步以避免在每个循环周期之前出现死锁。

关于"This seems now too trivial to be a compiler bug",您可能会惊讶于编译器如何错误地处理看似微不足道的事情。与 coarrays 相关的事情很少。

考虑以下相关程序:

  implicit none
  integer i[*]

  do i=1,1
     sync all
     print '(I1)', i[1]
  end do

end

我得到了最初令人惊讶的输出

1
2

当 运行 在 ifort 2018.1 下有两张图片时。

让我们看看发生了什么。

在我的循环中,当图像同步时,i[1] 首先具有值 1。但是,当第二个图像访问该值时,它已被结束其迭代的第一个图像更改。

我们通过在 end do 之前添加一个额外的同步语句来解决这个小问题。

这个程序与问题之一有什么关系?在远程图像上测试值和更新它的图像之间同样缺乏同步。

在同步和其他图像测试值 co_missionAccomplished[1] 之间,第一张图像可能会四处奔波并更新 counter,然后 co_missionAccomplished。某些图像可能会在第一次迭代时看到退出状态。