Isend/Irecv 不起作用,但 Send/Recv 可以

Posted

技术标签:

【中文标题】Isend/Irecv 不起作用,但 Send/Recv 可以【英文标题】:Isend/Irecv doesn`t work but Send/Recv does 【发布时间】:2013-08-20 14:47:14 【问题描述】:

当我使用 Send/Recv 时,我的代码可以工作,但是当我用 Isend/Irecv 替换 Send/Recv 时,它会产生分段错误。但在去其他任何地方之前,我想验证下面的 sn-p 是否看起来不错。

其余的代码应该没问题,因为 Send/Recv 可以工作;但我没有粘贴在这里,因为它的代码很长。

    INTEGER :: IERR,TASKID,NUMTASKS,SPANX,SPANY,SPANZ,PROCSX,PROCSY,PROCSZ,STAT,STATUS(MPI_STATUS_SIZE),ISTAT(MPI_STATUS_SIZE,52)
    INTEGER,DIMENSION(1:52) :: REQ

 ALLOCATE(RCC(IIST:IIEND,JJST:JJEND,KKST:KKEND),STAT=IERR)  
 IF (IERR /=0) PRINT*,'ERROR IN RCC BY',TASKID

 DO I=1,52
 REQ(I)=MPI_REQUEST_NULL  
 ENDDO

 IF (TASKID.NE.0) THEN   
 NT=TASKID
 CALL MPI_ISEND(RCC(IIST:IIEND,JJST:JJEND,KKST:KKEND),SIZE(RCC),MPI_DOUBLE_PRECISION,0,8,MPI_COMM_WORLD,REQ(NT),IERR)
 ENDIF

 IF (TASKID.EQ.0) THEN     
 DO NT = 1,26
 CALL MPI_IRECV(CC(RSPANX(NT):RSPANXE(NT),RSPANY(NT):RSPANYE(NT),RSPANZ(NT):RSPANZE(NT)),SIZECC(NT),MPI_DOUBLE_PRECISION,NT,8,MPI_COMM_WORLD,REQ(NT+26),IERR)   
 ENDDO       
 ENDIF  

 CALL MPI_WAITALL(52,REQ,ISTAT,IERR)

  DEALLOCATE(RCC,STAT=IERR) 
  IF (IERR /=0) PRINT*,'ERROR IN DEALLOCATE RCC BY',TASKID 

  CALL MPI_FINALIZE(IERR)
  RETURN
  END

但是,当我使用 Isend/Irecv 时,以下行不会给出分段错误。

  CALL MPI_IRECV(CC(RSPANX(NT),RSPANY(NT),RSPANZ(NT)),SIZECC(NT),MPI_DOUBLE_PRECISION,NT,8,MPI_COMM_WORLD,REQ(NT+26),IERR)  

【问题讨论】:

不是答案,但我建议使用调试器在此处查找分段错误的根源。 【参考方案1】:

使用数组部分调用异步通信例程,如 MPI_ISENDMPI_IRECV,例如RCC(IIST:IIEND,JJST:JJEND,KKST:KKEND),非常危险。原因是由于旧 Fortran 标准的限制,大多数 MPI 实现没有为这些例程提供适当的接口,编译器将数据从数组部分复制到临时连续存储中,然后传递给子例程。分段错误可能是由于在实际数据传输发生之前从MPI_ISEND/MPI_IRECV 返回时释放了此临时存储。您可以通过手动分配连续数组并将数据复制到那里来防止这种情况发生。

另一方面,CC(RSPANX(NT),RSPANY(NT),RSPANZ(NT)) 不是指数组的一部分,而是指单个元素的位置。在这种情况下,不会创建数据的临时副本。

MPI-3.0 提供了一组改进的 Fortran 绑定 mpi_f08,它使用 Fortran 2008 和 TS 29113 中的现代特性用 ASYNCHRONOUS 属性标记此类参数,并允许安全传递不同维度的数组 (@987654329 @)

【讨论】:

感谢您的回答。我会尝试你的建议。

以上是关于Isend/Irecv 不起作用,但 Send/Recv 可以的主要内容,如果未能解决你的问题,请参考以下文章

MPI_Irecv 中的致命错误:正在中止作业

Angular 的 $http.post 不起作用,它的 $http... 也不起作用,但 jQuerys ajax 起作用。为啥?

Laravel Admin 路由不起作用,但其他路由不起作用

同步方法不起作用,但同步块起作用,为啥?

DirectSoundOut 不起作用,但 WaveOut 起作用

Javascript:为啥有时 alert() 不起作用但 console.log() 起作用?