【问题标题】:OpenACC loop private clause and race conditionOpenACC 循环私有子句和竞争条件
【发布时间】:2019-08-15 21:14:41
【问题描述】:

我正在尝试将工作人员私有数组与 OpenACC 一起使用,但我一直得到错误的结果。我想有一些比赛条件问题正在发生,但我找不到在哪里。

我正在使用 PGI 编译器(18.10,OpenPower)并编译:

pgf90 -gopt -O3 -Minfo=all -Mcuda=ptxinfo -acc -ta=tesla:cc35 main.F90

这是我想要实现的一个最小示例:

#define lx 7000
#define ly 500

program test
  implicit none
  integer :: tmp(ly,1), a(lx,ly), b(lx,ly)
  integer :: x,y,i

  do x=1,lx
     do y=1,ly
        a(x,y) = x+y
     end do
  end do

  !$acc parallel num_gangs(1)                                                                                                                                                                                                                 
  !$acc loop worker private(tmp)                                                                                                                                                                                                              
  do x=1,lx
     !$acc loop vector                                                                                                                                                                                                                        
     do y=1,ly
        tmp(y,1) = -a(x,y)
     end do
     !$acc loop vector
     do y=1,ly
        b(x,y) = -tmp(y,1)
     end do
  end do
  !$acc end parallel                                                                                                                                                                                                                          

  print *, "check"
  do x=1,lx
     do y=1,ly
        if(b(x,y) /= x+y) print *, x, y, b(x,y), x+y
     end do
  end do
  print*, "end"
end program

我的预期是得到 b == a,但事实并非如此。

请注意,我定义了tmp(ly,1),因为当我将tmp(ly) 定义为一维数组时,我得到了预期的结果。即使它适用于一维数组,我也不确定它是否完全遵守 OpenACC 标准。

我错过了什么吗?

编辑:最后一个循环检查是否 a==b 并打印错误的值。预期的输出(我在禁用 OpenACC 的情况下得到)是:

  check
  end

启用 OpenACC 后我得到的结果是这样的(运行之间的变化):

check
            1            1            5            2
            1            2            6            3
            1            3            7            4
[...]
  end

【问题讨论】:

    标签: fortran gpu openacc pgi


    【解决方案1】:

    看起来像一个编译器问题,其中“tmp”由工作人员共享,而不是每个工作人员都获得一个私有副本。这反过来会导致您的代码中出现竞争条件。

    我已向 PGI (TPR#27025) 提交了一份问题报告,并将其发送给我们的工程师进行进一步调查。

    解决方法是在外循环上使用“gang”而不是“worker”,或者如您所见,将“tmp”设为一维数组。

    更新:TPR #27025 已在 PGI 19.7 版本中修复。

    【讨论】:

    • 我在哪里可以跟踪您提交的问题报告的进展情况?
    • 我们没有可公开访问的错误跟踪器。对于状态,您可以发送电子邮件至 trs@pgroup,com 的 PGI 客户服务。
    【解决方案2】:

    这两个acc loop

     !$acc loop vector                                                                                                                                                                                                                        
     do y=1,ly
        tmp(y,1) = -a(x,y)
     end do
     !$acc loop vector
     do y=1,ly
        b(x,y) = -tmp(y,1)
     end do
    

    会同时在gpu上执行。也就是说,它们是并行执行的。为了确保 tmp 在第二个循环中使用之前在第一个循环中被分配为正确的值,它们必须位于不同的 acc parallel 构造上。

    正确的代码如下所示:

      do x=1,lx
          !$acc parallel loop                                                                                                                                                                                                                     
          do y=1,ly
              tmp(y,1) = -a(x,y)
          end do
          !$acc parallel loop                                                                                                                                                                                                                     
          do y=1,ly
              b(x,y) = -tmp(y,1)
          end do
      end do
    

    【讨论】:

      猜你喜欢
      • 2017-03-24
      • 1970-01-01
      • 2018-07-24
      • 2021-12-09
      • 1970-01-01
      • 1970-01-01
      • 2020-07-12
      • 2012-01-01
      • 1970-01-01
      相关资源
      最近更新 更多