使用例行调用在并行区域中使用PGI而不是Cray进行编译时发生运行时错误

时间:2019-05-02 10:15:16

标签: fortran openacc pgi

我有一个问题:当我使用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

在例程中,我包含!$ acc例程seq。看起来像这样:

   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)

1 个答案:

答案 0 :(得分:0)

由于错误是段错误,这意味着问题出在主机端。

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

!$acc parallel present(var2,var3)

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

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