mpi_recv只收到mpi_send发送的一半数据?完全糊涂了

时间:2017-11-20 05:57:59

标签: arrays parallel-processing fortran mpi

我正在和fortran一起学习mpi。我写了一个简单的代码,如下所示。

program arraypractice
use mpi
    integer pid, np, ierr, arraysize, i,msg, status(mpi_status_size)       
    integer dcount
    real*8  f(10), f1(10)

    call mpi_init(ierr)
    call mpi_comm_size(mpi_comm_world, np, ierr)
    call mpi_comm_rank(mpi_comm_world, pid, ierr)

    if(pid==0) then
          do i = 1, 10
          f(i)=float(i)
          enddo
    endif

        msg = 1

    if(pid==0) then
         call mpi_send(f(1),6,mpi_real,1,msg,mpi_comm_world,ierr)
    endif

    if(pid==1) then
        call mpi_recv(f1(1),6,mpi_real,0,msg,mpi_comm_world,status,ierr)

        call mpi_get_count(status,mpi_real,dcount,ierr)
        print *,dcount
        do i= 1, 6
          print *,f1(i)
        enddo
    endif

    call mpi_finalize(ierr)
end

我正在使用“mpif90”命令编译代码,然后在我的带有Arch Linux的i5双核笔记本电脑上使用“mpirun -n 2 a.out”命令运行它。我的输出看起来像,

          6
   1.0000000000000000     
   2.0000000000000000     
   3.0000000000000000     
   0.0000000000000000     
   0.0000000000000000     
   0.0000000000000000

我完全不清楚为什么最后3个号码没有被更新。每次mpi_recv只收到mpi_send发送的数据的一半时。我希望输出是

          6
   1.0000000000000000     
   2.0000000000000000     
   3.0000000000000000     
   4.0000000000000000     
   5.0000000000000000     
   6.0000000000000000

任何帮助都会非常感激。

2 个答案:

答案 0 :(得分:2)

数组元素的类型与您为MPI调用提供的数据类型之间存在类型不匹配。 real*8表示64位双精度数,而MPI_REAL对应于(通常)32位单精度类型real。因此,MPI仅发送前半部分数据。

要么取消*8中的real*8以使用单精度,要么将MPI_REAL替换为MPI_DOUBLE_PRECISIONMPI_REAL8。第二个MPI数据类型(MPI_REAL8)是可选的,可能并非在所有MPI库中都可用。

答案 1 :(得分:-2)

您还应注意,MPI保证仅适用于Fortran 77和C.不保证可以使用Fortran 90(或更高版本)或C ++。 MPI不像普通的库,它直接与内存布局混淆,并且可以覆盖与您所做的MPI调用无关的局部变量。例如,我在MPI中崩溃只是因为我有一个局部变量integer i。这个变量在我对MPI的调用中没有任何作用。当我偶然发现它integer, save :: i时(所以不在堆栈中)一切正常!