gpt4 book ai didi

fortran - Isend/Irecv 不起作用,但 Send/Recv 起作用

转载 作者:行者123 更新时间:2023-12-02 14:24:57 28 4
gpt4 key购买 nike

当我使用 Send/Recv 时,我的代码可以工作,但是当我用 Isend/Irecv 替换 Send/Recv 时,它会产生段错误。但在去其他地方之前,我想验证一下以下代码片段是否看起来很重要。

其余代码应该没问题,因为 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)  

最佳答案

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

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

MPI-3.0 提供了一组改进的 Fortran 绑定(bind) mpi_f08,它使用 Fortran 2008 和 TS 29113 中的现代功能来使用 ASYNCHRONOUS 属性标记此类参数,并启用安全传递不同维度的数组 (TYPE(*), DIMENSION(..))

关于fortran - Isend/Irecv 不起作用,但 Send/Recv 起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18303064/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com