OpenMP / OpenACC实施与gcc / PGI编译器之间的结果不一致

问题描述

我有一个较大的Fortran程序正在尝试转换,以便计算密集型部分将在使用OpenMP和/或OpenACC的NVidia GPU上运行。在开发期间,我遇到了一些问题,以了解如何在模块中声明的变量如何在GPU(以及其中一些也在CPU)上执行的子例程中使用。因此,我通过尝试并添加相应的OpenMP和OpenACC指令,创建了一个小示例并进行了研究。在此消息的末尾,我已经包括了构成我的示例的三个文件。

就像我以为我已经理解了事情并且示例程序可以正常工作一样,我注意到了以下几点:

  • 我使用OpenMP指令使用gcc 10.2编译程序:
gfortran -O3 -fopenmp -Wall -Wextra test_link.f90 parameters.f90 common_vars.f90 -o test_link

结果符合预期,即数组XMO的所有元素均为1,DCP为2,IS1为3,IS2为24。

  • 我使用OpenACC指令使用PGI编译器19.10社区版编译程序:
pgfortran -O4 -acc -ta=tesla,cc35 -Minfo=all,mp,accel -Mcuda=cuda10.0 test_link.f90 common_vars.f90 parameters.f90 -o test_link

结果与上面相同。

  • 我使用OpenACC指令使用gcc 10.2编译程序:
gfortran -O3 -fopenacc -Wall -Wextra test_link.f90 parameters.f90 common_vars.f90 -o test_link

XMO,DCP和IS1数组的结果正确,但是IS2的所有元素均为0。很容易验证变量NR的值为0以获得此结果。

我的理解是,示例中的OpenMP和OpenACC版本是等效的,但我无法弄清为什么OpenACC版本仅适用于PGI编译器而不适用于gcc。

如果可能,请提供不需要在代码中进行更改而仅在指令中进行更改的解决方案。正如我提到的,我的原始代码要大得多,包含更多的模块变量,并在要在GPU上执行的代码中调用了更多的子例程。对该代码进行更改将更加困难,显然,我更愿意仅在确实必要时进行更改。

提前谢谢!

我的示例文件如下。

File parameters.f90
MODULE PARAMETERS
  IMPLICIT NONE
  INTEGER,PARAMETER :: MAX_SOURCE_POSITIONS = 100
END MODULE PARAMETERS
File common_vars.f90
MODULE COMMON_VARS
  USE PARAMETERS
  IMPLICIT NONE

!$OMP DECLARE TARGET TO(NR)
  INTEGER :: NR
!$ACC DECLARE COPYIN(NR)

END MODULE COMMON_VARS
File test_link.f90
      SUBROUTINE TEST()
       USE COMMON_VARS
        IMPLICIT NONE
!$OMP DECLARE TARGET
!$ACC ROUTINE SEQ
        INTEGER I
        I = NR
      END SUBROUTINE TEST


      PROGRAM TEST_LINK

      USE COMMON_VARS
      USE PARAMETERS

      IMPLICIT NONE

      INTERFACE
        SUBROUTINE TEST()
!$OMP DECLARE TARGET
!$ACC ROUTINE SEQ
        END SUBROUTINE TEST
      END INTERFACE

      REAL    :: XMO(MAX_SOURCE_POSITIONS),DCP(MAX_SOURCE_POSITIONS)
      INTEGER :: IS1(MAX_SOURCE_POSITIONS),IS2(MAX_SOURCE_POSITIONS)

      INTEGER :: X,Y,Z,MAX_X,MAX_Y,MAX_Z,ISOUR

      MAX_X = 3
      MAX_Y = 4
      MAX_Z = 5
      NR    = 6

!$OMP TARGET UPDATE TO(NR)
!$OMP TARGET MAP(TOFROM:IS1,IS2,DCP,XMO)
!$OMP TEAMS DISTRIBUTE PARALLEL DO COLLAPSE(3)
!$ACC UPDATE DEVICE(NR)
!$ACC PARALLEL LOOP GANG WORKER COLLAPSE(3) INDEPENDENT &
!$ACC COPY(IS1,XMO)
      DO X = 1,MAX_X
         DO Y = 1,MAX_Y
            DO Z = 1,MAX_Z

               ISOUR = (X - 1)*MAX_Y*MAX_Z + (Y - 1)*MAX_Z + Z

               XMO(ISOUR) = 1.0
               DCP(ISOUR) = 2.0
               IS1(ISOUR) = 3
               IS2(ISOUR) = 4   * NR

               CALL TEST()

            ENDDO  ! End of z loop
         ENDDO     ! End of y loop
      ENDDO        ! End of x loop
!$ACC END PARALLEL LOOP
!$OMP END TEAMS DISTRIBUTE PARALLEL DO
!$OMP END TARGET

      DO X = 1,MAX_Z

               ISOUR = (X - 1)*MAX_Y*MAX_Z + (Y - 1)*MAX_Z + Z

               WRITE(*,*) 'ISOUR = ',ISOUR,'XMO = ',XMO(ISOUR),'DCP = ',DCP(ISOUR),'IS1 = ',IS1(ISOUR),'IS2 = ',IS2(ISOUR)

            ENDDO  ! End of z loop
         ENDDO     ! End of y loop
      ENDDO        ! End of x loop

      END PROGRAM TEST_LINK

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...