Fortran 在具有例程调用的并行区域中使用PGI而不是Cray进行编译时出现运行时错误

Fortran 在具有例程调用的并行区域中使用PGI而不是Cray进行编译时出现运行时错误,fortran,openacc,pgi,Fortran,Openacc,Pgi,我有一个问题:当我用PGI而不是Cray编译时,我的代码确实给了我一个运行时错误。当代码进入并行区域时失败,并给我一个分段错误 我尝试了几种方法,发现将标量(var4,请参阅代码)传递给子例程是正确的。但是将数组(var3,参见代码)传递给例程失败 使用Cray编译代码时没有任何问题,但使用PGI时会出现问题 因此,我的问题是:PGI和Cray在设备上分配阵列的方式是否有差异 调用的并行区域如下所示: !$acc data present(var2,var3,var4) !$

我有一个问题:当我用PGI而不是Cray编译时,我的代码确实给了我一个运行时错误。当代码进入并行区域时失败,并给我一个分段错误

我尝试了几种方法,发现将标量(var4,请参阅代码)传递给子例程是正确的。但是将数组(var3,参见代码)传递给例程失败

使用Cray编译代码时没有任何问题,但使用PGI时会出现问题

因此,我的问题是:PGI和Cray在设备上分配阵列的方式是否有差异

调用的并行区域如下所示:

     !$acc data present(var2,var3,var4)
     !$acc parallel
       !$acc loop gang vector collapse(2) private(var1)
       DO j = 1, jend
         DO i = 1, iend
           IF (var2(i,j) .gt. 100.0) THEN
             CALL routine_seq ( var3(i,j,:),  &
                                var4(i,j),    &
                                var1)
           END IF
         END DO
       END DO
       !$acc end parallel
   SUBROUTINE routine_seq(var3,var4)
    !$acc routine seq
    REAL (KIND=wp), DIMENSION( : ),             &
         INTENT( IN ) ::                               var3

    REAL (KIND=wp), DIMENSION( : ),             &
         INTENT(  IN ) ::                               var4

    REAL (KIND=wp),                             &
         INTENT( OUT ) ::                               var1
在日常生活中,我有最好的选择$包括acc例行程序。看起来是这样的:

     !$acc data present(var2,var3,var4)
     !$acc parallel
       !$acc loop gang vector collapse(2) private(var1)
       DO j = 1, jend
         DO i = 1, iend
           IF (var2(i,j) .gt. 100.0) THEN
             CALL routine_seq ( var3(i,j,:),  &
                                var4(i,j),    &
                                var1)
           END IF
         END DO
       END DO
       !$acc end parallel
   SUBROUTINE routine_seq(var3,var4)
    !$acc routine seq
    REAL (KIND=wp), DIMENSION( : ),             &
         INTENT( IN ) ::                               var3

    REAL (KIND=wp), DIMENSION( : ),             &
         INTENT(  IN ) ::                               var4

    REAL (KIND=wp),                             &
         INTENT( OUT ) ::                               var1
var3和var4的分配方式如下:

    ALLOCATE ( var3(iend,jend,kend) , STAT=ierr); IF (ierr/=0) istat=ierr
    ALLOCATE ( var4(iend,jend) , STAT=ierr); IF (ierr/=0) istat=ierr
    !$acc enter data create(var3,var4)

由于错误是seg故障,这意味着问题出在主机端

尝试在“平行”区域添加“present”子句:

虽然由于没有提供完整的复制示例,所以有点难以确定,但我对这个问题的最佳猜测是,编译器无法正确确定隐式复制到区域中需要多少数组,因为var3除了作为调用的参数外,在该区域中没有使用。PGI将尝试仅隐式复制数组的最小数量。添加“present”将禁用隐式副本,而仅当阵列在设备上已经存在设备副本时,才让它检查present表。或者,您可以使用“copy(var2,var3)”作为“present_或_copy”语义,其中present检查将针对整个数组而不是子集


要查看编译器对隐式副本使用的内容,请尝试添加“-Minfo=accel”以启用编译器反馈消息。

欢迎使用堆栈溢出。请拿着这本书学习。然后,给我们一个清晰的描述,你想做什么,你错了什么,你期望得到什么,以及一个简单的答案。在通话中使用:
var3(i,j:)
so3d,在分配中使用
var3(iend,jend)
so2d。你没有收到编译警告/错误吗?是的,你是对的。我编辑了这个问题。使代码可读是一个错误。但我们至少需要看到声明、例程,但最好是一个显示问题的MWE。请尝试使用调试选项和边界检查进行编译,以查明问题所在。