OpenMPI MPI_Send和MPI_Recv结构挂起

时间:2014-03-18 16:35:42

标签: fortran mpi

我在Fortran中实现了一个MPI通信结构,主机为每个从站确定了以后必须处理的域的大小。我在9个进程(一个主服务器和8个从服务器)上运行以下代码:

if (rank==root) then  

  ! (Some irrelevant calculations here)

  ! Send information to slaves
  do i=1,numslaves
    print*, "Sending information to process", i
    nrowLocal=nrowLocalArray(i)
    mpiTag=1
    call MPI_SEND(nrowLocal,1,MPI_INTEGER,i,mpiTag,MPI_COMM_WORLD,ierr)
    print*, "ierr send1=", ierr
    call MPI_RECV(ctrl,1,MPI_INTEGER,i,mpiTag,MPI_COMM_WORLD,status,ierr)
    print*, "ierr recv1=", ierr

    firstRow = firstRowArray(i)
    mpiTag=2
    call MPI_SEND(firstRow,1,MPI_INTEGER,i,mpiTag,MPI_COMM_WORLD,ierr)
    print*, "ierr send2=", ierr
    call MPI_RECV(ctrl,1,MPI_INTEGER,i,mpiTag,MPI_COMM_WORLD,status,ierr)
    print*, "ierr recv2=", ierr

  end do

  print*, "Master distributed a total of ", nrow, " among ", numslaves, " slaves"

else  ! Slaves part
  print*, "ready, process", rank
  nrowGlobal = nrow

  ! Get information from master
  mpiTag=1
  call MPI_RECV(nrowLocal,1,MPI_INTEGER,root,mpiTag,MPI_COMM_WORLD,status,ierr)
  call MPI_SEND(rank,1,MPI_INTEGER,root,mpiTag,MPI_COMM_WORLD,ierr)

  mpiTag=2
  call MPI_RECV(firstRow,1,MPI_INTEGER,root,mpiTag,MPI_COMM_WORLD,status,ierr)
  call MPI_SEND(rank,1,MPI_INTEGER,root,mpiTag,MPI_COMM_WORLD,ierr)

  nrow = nrowLocal
  lastRow = firstRow + nrow
 print*, "Process number ", rank, " has a total of ", nrowLocal, " rows, starting at row", firstRow

end if

此代码包含在从程序的另一部分调用的子例程中。所有变量都在一个单独的模块中声明,use d。

我的问题是,在主设备将信息发送到1或2个从设备后,代码会挂起。

print*,到日志文件的输出告诉我以下内容:

  • 所有奴隶打印"准备好"消息,因此,程序只是在等待尚未初始化的进程。
  • 成功执行此部分代码的从属进行并从程序的下一部分写入输出。
  • 打印的ierr错误代码始终为0.
  • 主人打印的最后一条消息是"Sending information to process",其中包含下一行的奴隶编号。

首先,我尝试没有从MPI_SEND从奴隶回到主人(和相应的MPI_RECV,然后插入他们,认为他们可以解决问题(但它没有改变什么)。

另外,我尝试在MPI_ANY_TAGSEND语句中使用RECV而不是自己定义标记,但在这种情况下,甚至不执行SEND

我已经读过一些其他答案,大缓冲区大小可能会有问题,但由于我当时只发送一个整数,我不认为这是相关的这里。

我正在使用OpenMPI Intel 1.4.3。在Linux(CentOS 5.5)上。

有人能发现这里的错误吗?任何帮助是极大的赞赏!我可能会遗漏一些明显的东西,因为我对MPI和Fortran都很陌生。


编辑:

1)status在一个单独的模块中声明:

integer,allocatable :: status(:)

并在MPI初始化后分配

allocate(status(MPI_STATUS_SIZE))

2)输出如下:

 ready, process          1
 ready, process          7
 ready, process          4
 ready, process          6
 ready, process          3
 ready, process          5
 ready, process          2
 Sending information to process           1
 ierr send1=           0
 ierr recv1=           0
 ierr send2=           0
 Process number            1  has a total of           21  rows, starting at row
 ierr recv2=           0
           1
 (Output from the next part of the program from Process 1)
 ready, process           8
 Sending information to process           2

注意:从底部开始的第4行的1是从第6行到底部的延续。

0 个答案:

没有答案