Fortran MPI_Isend和MPI_Irecv

问题描述 投票:0回答:1

我对MPI_Isend和MPI_Irecv有问题:接收向量永远不会正确发送。该代码用Fortran编写。

每个进程都有许多我想向其发送值的接触过程。我要发送的值包含4个向量,它们是每个进程称为variables的类型的一部分。

这是我使用的代码:

program isend_test
use mpi

real, dimension(:,:,:), allocatable :: receivedValues
real, dimension(:,:), allocatable :: sendReals
integer, dimension(:,:), allocatable :: requestSend
integer, dimension(:,:), allocatable :: requestReceive
integer, dimension(:), allocatable :: neighbours
integer, dimension(mpi_status_size) :: status
integer :: ierr, currentNeighbour, k, me, nTasks, nValues, nNeighbours, addedNeighbours

call MPI_init(ierr)

call MPI_COMM_RANK(MPI_COMM_WORLD, me, ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, nTasks, ierr)

nNeighbours = 2

! Only 3 values for each variable to keep it simple
nValues = 3

allocate(receivedValues(nNeighbours,4,nValues))
allocate(sendReals(4,nValues))
allocate(requestSend(4,nNeighbours))
allocate(requestReceive(4,nNeighbours))
allocate(neighbours(2))

receivedValues = -9999

! Initializing neighbours - Every process is adjacent to every other process in this example
addedNeighbours = 0
do j = 0,2
    if (j == me) then
        cycle
    endif
    addedNeighbours = addedNeighbours + 1
    neighbours(addedNeighbours) = j
enddo

! fill in some values to send
do j = 1,4
   do i=1,nValues
      sendReals(j,i) = j + 10*me + 100*i
   enddo
enddo

do j = 1,4
    do i = 1,nNeighbours
        call mpi_isend(sendReals(j,:), nValues, mpi_real, neighbours(i), j, MPI_COMM_WORLD, requestSend(j,i), ierr)
        call mpi_irecv(receivedValues(i, j, :), nValues, mpi_real, neighbours(i), j, MPI_COMM_WORLD, requestReceive(j,i), ierr)
    enddo
enddo


do j = 1,4
    do i = 1,nNeighbours
        call mpi_wait(requestSend(j,i), status, ierr)
        call mpi_wait(requestreceive(j,i), status, ierr)
    enddo
enddo

write(*,*)receivedValues

call MPI_finalize(ierr)
end

我知道数据类型是正确的(它们与MPI_SendMPI_Recv一起使用),并且邻居和标记的整个匹配也是正确的,因为代码可以正确运行。但是,如果我在同步之前的开始处设置了receivedValues = -9999,则这些值不会更改。

我知道可以更高效地完成代码,但是我进行了大量更改以发现错误而没有成功……有人有想法吗?缓冲区可能有问题,我只是找不到...

顺便说一句:发送和接收sendReals(j,1)neighbours(i), j, 1)也不起作用...

parallel-processing fortran mpi fortran90 openmpi
1个回答
1
投票
mpi_irecv(receivedValues(i, j, :)

因此,仅当MPI_SUBARRAYS_SUPPORTED.true.时才有效(并且它不在Open MPI中,对于MPICH和mpi_f08绑定可能是这种情况。

不仅您获取的数据不正确,而且还很可能导致静默数据损坏。

您可以重新排列receivedValues数组,或使用派生的数据类型并使用receivedValues(i,j,1)作为接收缓冲区。

© www.soinside.com 2019 - 2024. All rights reserved.